时间:2021-05-22
在python中,给一个对象赋值,实际上就是对象对内存空间存储的值的引用。当我们把对象赋值给另一个变量的时候,这个变量并没有拷贝这个对象,而只是拷贝了这个对象的引用而已。
一般情况下我们会通过三种方法来实现拷贝对象的引用。
直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的变量也会做相同的改变。其实就是对‘对象'的引用
示例:
>>> list_demo = [2, 4, 6]>>> a = list_demo>>> print(a)[2, 4, 6]>>> id(list_demo)65006808>>> id(a)65006808>>> list_demo.append(8)>>> print(list_demo)[2, 4, 6, 8]>>> print(a)[2, 4, 6, 8]>>> id(list_demo)65006808>>> id(a)65006808>>>通过 id() 函数我们可以得出,变量 list_demo 与 a 指向的都是同一个内存空间地址,当被赋值的 list_demo改变,被赋值的 a 同样会做相同的改变。这种现象普遍存在于 Python 之中,这种赋值的方式实现了 “假装” 拷贝,真实的情况还是两个变量和同一个对象之间的引用关系。
import copy 模块的 copy.copy() 方法,该方法只拷贝父对象,没有拷贝子对象。且浅拷贝是创建一块新的内存空间,但是内存空间内的元素的地址均是父对象元素的地址的拷贝。所以当父对象内部的子对象发生改变时,拷贝对象的内部的子对象也会跟着改变。
示例:
>>> list_demo1 = [2, 4, 6, [8, 10]]>>> a = list_demo1>>> print(list_demo1)[2, 4, 6, [8, 10]]>>> print(a)[2, 4, 6, [8, 10]]>>>>>>>>> import copy>>> b = copy.copy(list_demo1)>>> id(list_demo1)65103472>>> id(b)6011200>>> list_demo1.append(12)>>> print(list_demo1)[2, 4, 6, [8, 10], 12]>>> list_demo1[3][8, 10]>>>>>>>>>>>> list_demo1[3].append('hello')>>> print(list_demo1)[2, 4, 6, [8, 10, 'hello'], 12]>>> print(b)[2, 4, 6, [8, 10, 'hello']]>>> list_demo1[3][8, 10, 'hello']>>> b[3][8, 10, 'hello']>>>>>>>>>>>> id(list_demo1)65103472>>> id(b)6011200>>> id(list_demo1[3])64679128>>> id(b[3])64679128>>>从上述代码可以看出,在执行浅拷贝的时候,浅拷贝实际上只拷贝引用,不拷贝内容。同时,浅拷贝会针对父对象的子对象进行判断,当父对象的子对象发生改变时,拷贝对象内的子对象同时也跟着改变。
import copy 模块的 copy.deepcopy() 方法,深拷贝与浅拷贝相反,就是彻彻底底的拷贝,完全的拷贝了父对象及子对象,同时指向一个新的内存空间地址。此时,虽然源对象与拷贝对象的内容是一样的,但是不管针对谁进行改动,另一个是丝毫不会受到影响的。
>>> list_demo2 = [2,3,4]
>>> c= copy.deepcopy(list_demo2)
>>> print(list_demo2)
[2, 3, 4]
>>> print(c)
[2, 3, 4]
>>> id(list_demo2)
6011440
>>> id(c)
6012440
>>> list_demo2.append(['a','b'])
>>> c.append([5,6])
>>> print(list_demo2)
[2, 3, 4, ['a', 'b']]
>>> print(c)
[2, 3, 4, [5, 6]]
>>> list_demo2[3].append('c')
>>> c[3].append(7)
>>> print(list_demo2)
[2, 3, 4, ['a', 'b', 'c']]
>>> print(c)
[2, 3, 4, [5, 6, 7]]
>>>
从上述代码示例可以看出 list_demo2 与 c 相互独立,无论 list_demo2 与 c本身进行了修改,或者各自的子对象进行了修改 都没有互相影响。
总结
赋值的本质就是将一个对象的内存空间地址赋值给一个变量,让变量指向该内存空间地址。
浅拷贝是拷贝了源对象的引用,并创建了一个新的内存空间地址。但是引用的对象的子对象的地址仍然是源对象的,所以当源对象的子对象发生改变时,拷贝对象内的子对象同时也跟着改变。
深拷贝就是彻底的拷贝,完全的拷贝了父对象及子对象,同时指向一个新的内存空间地址。源对象与拷贝对象之间的修改互不影响。
更多关于Python的赋值、深拷贝与浅拷贝的区别文章请查看下面的相关链接
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
python深拷贝和浅拷贝的区别是: 1、直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变。 2、copy浅拷贝,没有拷贝子
Python中关于对象复制有三种类型的使用方式,赋值、浅拷贝与深拷贝。他们既有区别又有联系,刚好最近碰到这一类的问题,研究下。一、赋值在python中,对象的赋
在Python中,经常要对一个list进行复制。对于复制,自然的就有深拷贝与浅拷贝问题。深拷贝与浅拷贝的区别在于,当从原本的list复制出新的list之后,修改
直接赋值和copy的区别:直接赋值:其实就是对象的引用(别名)。浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。深拷贝(deepcopy):copy
Python基础教程之浅拷贝和深拷贝实例详解网上关于Python的深拷贝和浅拷贝的文章很多,这里对三种拷贝进行比较并附实例,大家可以参考下一般的复制#encod