python之copy模块与深拷贝、浅拷贝

copy模块

使用copy模块来实现复制功能。

复制方法分为浅拷贝与深拷贝:

浅拷贝,

copy.copy(object)

对内存地址进行复制,目标对象和源对象指向同一内存片内存空间。

深拷贝,

copy.deepcopy(object)

为复制生成的对象也申请一个单独的内存空间,内存地址是自主分配的。

完成复制后,目标对象和源对象虽然存储数据是一样的,但是内存地址不同。

两个对象互不干涉。

例:

>>> jack = [‘jack‘, [‘age‘, ‘20‘]]
>>> import copy

//深拷贝
>>> james = copy.deepcopy(jack)

>>> james[0] = ‘james‘

>>> print jack, james
[‘jack‘, [‘age‘, ‘20‘]] [‘james‘, [‘age‘, ‘20‘]]
>>> james[1][1] = 18
>>> print jack, james
[‘jack‘, [‘age‘, ‘20‘]] [‘james‘, [‘age‘, 18]]

这时候他们之间就不会互相影响了。打印出每个人的内部元素每个id:

>>> [id(x) for x in jack]
[139132064, 3073507244L]
>>> [id(x) for x in james]
[139141632, 139157548]

他们的内部元素也都指向了不同的对象。

//浅拷贝

>>> love = copy.copy(jack)

>>> love[0] = ‘love‘

>>> print jack, love
[‘jack‘, [‘age‘, ‘20‘]] [‘love‘, [‘age‘, ‘20‘]]
>>> james[1][1] = 18
>>> print jack, love
[‘jack‘, [‘age‘, ‘18‘]] [‘love‘, [‘age‘, 18]]

>>> jack.append([‘sex‘,‘man‘])

>>> print jack

[‘jack‘, [‘age‘, ‘20‘], [‘sex‘, ‘man‘]]

>>> print love

[‘jack‘, [‘age‘, ‘20‘]]

copy()方法将源对象变量的内存数值复制给目标对象,两个对象共享同一存储区。

浅拷贝是创建一个新对象,但没有为新对象创建数据区。

因其中第一个元素字符串是不可变类型,所以更改会生成一个新的对象;第二个元素列表是可变类型,所以是在修改原来的对象。

浅拷贝后,在源对象中添加元素,目标对象不会受到影响。

用切片和list方法实现浅拷贝

>>> jack = [‘jack‘, [‘age‘, 20]]
>>> james = jack[:]
>>> anny = list(jack)

观察三者的id值,三者是不同的对象。

>>> print id(jack), id(tom), id(anny)

144846988 144977164 144977388

修改每个值中的名称并再次观察

>>> james[0] = ‘james‘
>>> anny[0] = ‘anny‘
>>> print jack, james, anny

[‘jack‘, [‘age‘, 20]] [‘james‘, [‘age‘, 20]] [‘anny‘, [‘age‘, 20]]

看起来一切正常,在为james和anny重新命名的时候,会重新创建一个’james’和’anny’对象,替换旧的’jack’对象。

但anny只有18岁,重新为anny定义岁数。

>>> anny[1][1] = 18
>>> print jack, james, anny
[‘jack‘, [‘age‘, 18]] [‘james‘, [‘age‘, 18]] [‘anny‘, [‘age‘, 18]]

很奇怪的情况,jack、james、anny的岁数都发生了改变,变成了18了。jack、tom、anny他们应当都是不同的对象,怎么会互相影响呢?看下jack,james,anny的内部元素每个元素id:

>>> [id(x) for x in jack]
[3073896320L, 3073777580L]
>>> [id(x) for x in james]
[144870744, 3073777580L]
>>> [id(x) for x in anny]

[144977344, 3073777580L]

由于list的第一个元素是不可变类型,所以源对象对应的list的第一个元素会使用一个新的对象。
但是list的第二个元素是一个可变类型,修改操作不会产生新的对象,所以修改结果会相应的反应到其他的上面。

一个综合的例子:

import copy

a = [1,2,3,[‘a‘,‘b‘]]

b = a

c = copy.copy(a)

d = copy.deepcopy(a)

a.append(4)

a[3].append(‘c‘)

print a,b,c,d

输出结果为:

[1,2,3,[‘a‘,‘b‘,‘c‘],4]  [1,2,3,[‘a‘,‘b‘,‘c‘],4]  [1,2,3,[‘a‘,‘b‘,‘c‘]]

[1,2,3,[‘a‘,‘b‘]]

结:

  • 使用切片[:]操作、使用工厂函数(如list/dir/set)、使用copy模块中的copy()函数实现拷贝就叫浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。

利用copy中的deepcopy方法进行拷贝就叫做深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。

注:使用=号仅仅在源对象的标签上又加了一层标签生成目标对象,其通过源对象的标签来获取值。

时间: 2024-08-28 06:26:17

python之copy模块与深拷贝、浅拷贝的相关文章

Python:使用copy模块深拷贝对象

Python语言中有深拷贝和浅拷贝的概念,那什么是深拷贝,浅拷贝呢? 浅拷贝(shallow copy):构造一个新的复合对象并将从原对象中发现的引用(也就是地址,而不是地址所指向的内容)插入该对象中.浅拷贝的实现方法有很多种,如工厂函数.切片操作.copy模块中的copy操作. 深拷贝(deep copy):也构造一个新的复合对象,但是遇到引用会继续递归拷贝其所指向的内容,也就是说他会针对引用所指向的对象继续执行拷贝,因此产生的对象不受其它对象操作的影响.深拷贝的实现需要依赖copy模块的de

python之copy模块与深、浅拷贝

copy模块 使用copy模块来实现复制功能. 复制方法分为浅拷贝与深拷贝: 浅拷贝, copy.copy(object) 对内存地址进行复制,目标对象和源对象指向同一内存片内存空间. 深拷贝, copy.deepcopy(object) 为复制生成的对象也申请一个单独的内存空间,内存地址是自主分配的. 完成复制后,目标对象和源对象虽然存储数据是一样的,但是内存地址不同. 两个对象互不干涉. 例: >>> jack = ['jack', ['age', '20']]>>>

python中copy模块

import copyperson = ['name',['saving',100]]#浅copy三种方式p1 = copy.copy(person)p2 = person[:]p3 = list(person) 结果 ['name',['saving',100]] 浅copy的用处: import copyperson = ['name',['saving',100]]p1 = person[:]p2 = person[:]p1[0] = 'husband'p2[0] = 'wife'p1[1

python深拷贝浅拷贝

Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: 按 Ctrl+C 复制代码 will = ["Will", 28, ["Python", "C#", "JavaScript"]]wilber = willprint id(will)print willprint [id(ele) for

python(41):copy拷贝(深拷贝deepcopy与浅拷贝copy)

Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1.copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2.copy.deepcopy 深拷贝 拷贝对象及其子对象 >>> import copy >>> a = [1,2,3,4,['a','b']] #原始对象 >>> b = a #赋值,传对象的引用 >>> c = copy.copy(a) >>&g

python copy模块

python copy模块 copy模块用于对象的拷贝操作 该模块只提供了两个主要的方法: copy.copy:浅复制 copy.deepcopy:深复制 直接赋值,深拷贝和浅拷贝的区别 直接赋值:简单地拷贝对象的引用,两个对象的id相同.就是对象的引用(别名),就是给当前内存中的对象增加一个“标签”而已.通过使用内置函数 id() ,可以看出指向内存中同一个对象. 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象.即浅复制只复制对象本身,没有复制该对象所引用的对象.A shallow

Python中的赋值(复制)、浅拷贝与深拷贝

https://zhuanlan.zhihu.com/p/54011712 首先需要了解下几个概念 变量:是一个系统表的元素,拥有指向对象的连接空间 对象:被分配的一块内存,存储其所代表的值 引用:是自动形成的从变量到对象的指针 类型:属于对象,而非变量 不可变对象:一旦创建就不可修改的对象,包括字符串.元组.数值类型 (该对象所指向的内存中的值不能被改变.当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址.) 可变对象:

python学习之copy模块

copy模块中有两个方法,copy.copy()和copy.deepcopy,这两个方法分别是用来实现浅拷贝和深拷贝.所谓浅拷贝就是只拷贝引用,拷贝后生成的两个变量仍然是同一个对象,即其中一个变化了,另一个也跟着变化.而对于深拷贝,则是拷贝数据,生成的两个变量是不同的对象,他们之间的变化互不影响.但有一点要注意,copy模块的两个拷贝方法中针对的深浅拷贝说的是待拷贝对象的元素,即不管是copy()方法还是deepcopy()方法,待拷贝对象本身都是深拷贝,生成的是两个不同的对象,举个例子说明:

包,logging模块,hashlib模块,openpyxl模块,深拷贝,浅拷贝

1 包 研究模块与包 还可以站另外两个角度分析不同的问题1.模块的开发者2.模块的使用者 什么是包? 它是一系列模块文件的结合体,表示形式就是一个文件夹 该文件夹内部通常会有一个__init__.py文件 包的本质还是一个模块 首次导入包: 先产生一个执行文件的名称空间 1.创建包下面的__init__.py文件的名称空间 2.执行包下面的__init__.py文件中的代码 将产生的名字放入包下面的__init__.py文件名称空间中 3.在执行文件中拿到一个指向包下面的__init__.py文