Python中的深拷贝和浅拷贝详解

   这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用、可变对象-不可变对象、拷贝等内容,需要的朋友可以参考下

  要说清楚Python中的深浅拷贝,需要搞清楚下面一系列概念:

  变量-引用-对象(可变对象,不可变对象)-切片-拷贝(浅拷贝,深拷贝)

  【变量-对象-引用】

  在Python中一切都是对象,比如说:3, 3.14, 'Hello', [1,2,3,4],{'a':1}......


  甚至连type其本身都是对象,type对象

  Python中变量与C/C++/Java中不同,它是指对象的引用,Python是动态类型,程序运行时候,会根据对象的类型

  来确认变量到底是什么类型。

  单独赋值: 比如说:

  复制代码 代码如下:

  >>> a = 3

  在运行a=3后,变量a变成了对象3的一个引用。在内部,变量事实上是到对象内存空间的一个指针


  因为Python的变量不过是对象的引用,或指向对象的指针,因此在程序中可以经常改变变量引用

  复制代码 代码如下:

  >>> x = 42 #变量绑定到整型对象

  >>> x = 'Hello' #现在又成了字符串

  >>> x = [1,2,3] #现在又成了列表

  专业表述如下:

  变量是一个系统表的元素,拥有指向对象的连接的空间

  对象是被分配的一块内存,存储其所代表的值

  引用是自动形成的从变量到对象的指针

  特别注意: 类型属于对象,不是变量

  比如像刚才的a=3, 整数对象3包含了两重信息

  1.值为3

  2.一个头部信息:告诉Pthyon,这是个整数对象[相当于一个指向int的指针]

  共享引用: 比如说:

  复制代码 代码如下:

  >>> a = 3

  >>> b = a

  在运行赋值语句b = a之后,变量a和变量b指向了同一个对象的内存空间.


  从上图可以看到,a和b,其id完全一样,指向同一个整数对象3,或者说同一块内存


  如果删掉a后, 不会影响b


  拷贝概念的引入就是针对:可变对象的共享引用潜在的副作用而提出的.

  【可变对象-不可变对象】

  在Python中不可变对象指:一旦创建就不可修改的对象,包括字符串,元祖,数字

  在Python中可变对象是指:可以修改的对象,包括:列表、字典

  上面说的a,b都是整数,整数是不可变对象,如果是可变对象的话,就是另外一回事了。

  复制代码 代码如下:

  >>> L1 = [2,3,4] #L1变量指向的是一个可变对象:列表

  >>> L2 = L1 #将L1值赋给L2后,两者共享引用同一个列表对象[1,2,3,4]

  >>> L1[0] = 200 #因为列表可变,改变L1中第一个元素的值

  >>> L1; L2 #改变后,L1,L2同时改变,因为对象本身值变了

  [200, 3, 4]

  [200, 3, 4]

  如果不想改变列表L2的值,有两种方法:切片 和 copy模块

  复制代码 代码如下:

  >>> L1 = [2,3,4]

  >>> L2 = L1

  >>> id(L1);id(L2) #共享引用一个可变对象

  45811784L

  45811784L

  >>> L2 = L1[:] #切片操作

  >>> id(L1);id(L2) #切片后,对象就不一样了

  45811784L

  45806920L

  >>> L1[0] = 200

  >>> L1;L2 #L1发生改变,L2没有变化

  [200, 3, 4]

  [2, 3, 4]

  【拷贝】

  1. 切片技术应用于所有的序列,包括:列表、字符串、元祖

  >>>但切片不能应用于字典。对字典只能使用D.copy()方法或D.deepcopy()方法.


  2. 深浅拷贝,即可用于序列,也可用于字典

  复制代码 代码如下:

  >>> import copy

  >>> X = copy.copy(Y) #浅拷贝:只拷贝顶级的对象,或者说:父级对象

  >>> X = copy.deepcopy(Y) #深拷贝:拷贝所有对象,顶级对象及其嵌套对象。或者说:父级对象及其子对象

  如果字典只有顶级对象:


  如果字典中嵌套对象:


  【结论】

  深浅拷贝都是对源对象的复制,占用不同的内存空间

  如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象

  如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝

  序列对象的切片其实是浅拷贝,即只拷贝顶级的对象

时间: 2025-01-01 08:49:30

Python中的深拷贝和浅拷贝详解的相关文章

Python对象的深拷贝和浅拷贝详解_python

本文内容是在<Python核心编程2>上看到的,感觉很有用便写出来,给大家参考参考! 浅拷贝 首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法.然后使用id函数来看看它们的标示符 复制代码 代码如下: # encoding=UTF-8   obj = ['name',['age',18]] a=obj[:] b=list(obj) for x in obj,a,b:     print id(x)   35217032 35227912 29943304   他们的id都不同,按

Python中的推导式使用详解

  这篇文章主要介绍了Python中的推导式使用详解,本文分别讲解了列表推导式.字典推导式.集合推导式使用实例,需要的朋友可以参考下 推导式是Python中很强大的.很受欢迎的特性,具有语言简洁,速度快等优点.推导式包括: 1.列表推导式 2.字典推导式 3.集合推导式 嵌套列表推导式 NOTE: 字典和集合推导是最近才加入到Python的(Python 2.7 和Python 3.1以上版). 下面简要介绍下: [列表推导式] 列表推导能非常简洁的构造一个新列表:只用一条简洁的表达式即可对得到

Python中的zipfile模块使用详解

  这篇文章主要介绍了Python中的zipfile模块使用详解,zipfile模块是用来操作zip文件,需要的朋友可以参考下 zip文件格式是通用的文档压缩标准,在ziplib模块中,使用ZipFile类来操作zip文件,下面具体介绍一下: class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]]) 创建一个ZipFile对象,表示一个zip文件.参数file表示文件的路径或类文件对象(file-like object);参

Python中tell()方法的使用详解

  这篇文章主要介绍了Python中tell()方法的使用详解,是Python入门学习中的基础知识,需要的朋友可以参考下 tell()方法返回的文件内的文件读/写指针的当前位置. 语法 以下是tell()方法的语法: ? 1 fileObject.tell() 参数 NA 返回值 此方法返回该文件中读出的文件/写指针的当前位置. 例子 下面的例子显示了tell()方法的使用. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #

Python中的rfind()方法使用详解

  这篇文章主要介绍了Python中的rfind()方法使用详解,是Python入门中的基础知识,需要的朋友可以参考下 rfind()方法返回所在子str 被找到的最后一个索引,或者-1,如果没有这样的索引不存在,可选择限制搜索字符串string[beg:end]. 语法 以下是rfind()方法的语法: ? 1 str.rfind(str, beg=0 end=len(string)) 参数 str -- 此选项指定要搜索的字符串 beg -- 这是开始索引,默认情况下为 0 end -- 这

Python中的rjust()方法使用详解

  这篇文章主要介绍了Python中的rjust()方法使用详解,是Python学习入门中的基础知识,需要的朋友可以参考下 rjust()该方法返回字符串合理字符串的右边的长度宽度.填充是通过使用指定的fillchar(默认为空格).如果宽度小于len(s)返回原始字符串. 语法 以下是rjust()方法的语法: ? 1 str.rjust(width[, fillchar]) 参数 width -- 这是字符串填充后总共的长度. fillchar -- 这是填充字符,默认为空格. 返回值 此方

Python中的choice()方法使用详解

 这篇文章主要介绍了Python中的choice()方法使用详解,是Python入门中的基础知识,需要的朋友可以参考下     choice()方法从一个列表,元组或字符串返回一个随机项. 语法 以下是choice()方法的语法: ? 1 choice( seq ) 注意:此函数是无法直接访问的,所以我们需要导入random模块,然后我们需要使用random对象来调用这个函数. 参数 seq -- 这可能是一个列表,元组或字符串... 返回值 该方法返回一个随机项. 例子 下面的例子显示了cho

Python中的变量和作用域详解_python

作用域介绍 python中的作用域分4种情况: L:local,局部作用域,即函数中定义的变量: E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的: G:globa,全局变量,就是模块级别定义的变量: B:built-in,系统固定模块里面的变量,比如int, bytearray等. 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB. x = int(2.9) # int bu

Python中运算符&quot;==&quot;和&quot;is&quot;的详解_python

前言 在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识).python type()(数据类型)和value(值).is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同.下面来看看具体区别在哪. Python中比较两个对象是否相等,一共有两种方法,简单来说,它们的区别如下:      is是比较两个引用是否指向了同一个对象(引用比较).      ==是比较两个对象是否相等. >>> a = [1, 2, 3]