Python的赋值、深拷贝与浅拷贝的区别详解
在python中,给一个对象赋值,实际上就是对象对内存空间存储的值的引用。当我们把对象赋值给另一个变量的时候,这个变量并没有拷贝这个对象,而只是拷贝了这个对象的引用而已。
一般情况下我们会通过三种方法来实现拷贝对象的引用。
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之中,这种赋值的方式实现了“假装”拷贝,真实的情况还是两个变量和同一个对象之间的引用关系。
Python浅拷贝
importcopy模块的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]] >>> >>> >>>importcopy >>>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 >>>
从上述代码可以看出,在执行浅拷贝的时候,浅拷贝实际上只拷贝引用,不拷贝内容。同时,浅拷贝会针对父对象的子对象进行判断,当父对象的子对象发生改变时,拷贝对象内的子对象同时也跟着改变。
Python深拷贝
importcopy模块的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赋值
赋值的本质就是将一个对象的内存空间地址赋值给一个变量,让变量指向该内存空间地址。
Python浅拷贝
浅拷贝是拷贝了源对象的引用,并创建了一个新的内存空间地址。但是引用的对象的子对象的地址仍然是源对象的,所以当源对象的子对象发生改变时,拷贝对象内的子对象同时也跟着改变。
Python深拷贝
深拷贝就是彻底的拷贝,完全的拷贝了父对象及子对象,同时指向一个新的内存空间地址。源对象与拷贝对象之间的修改互不影响。
更多关于Python的赋值、深拷贝与浅拷贝的区别文章请查看下面的相关链接
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。