Python中的引用,copy和deepcopy的区别

本文深入探讨Python中变量引用的工作原理,特别是针对复杂数据结构的引用行为,并对比了浅拷贝与深拷贝的区别。

Python中的引用,个人理解,与C中对地址赋值(仅针对于简单对象,即不可修改的对象,例如int)相似。

简单的例子:

a = [1, 2, 3]
b = a
b[0] = 4
print(a) --> [4, 2, 3]
print(b) --> [4, 2, 3]
del b[0]
a.append(4)
print(a) --> [2, 3, 4]
print(b) --> [2, 3, 4]

以上的例子相信不难理解,再看下一个:

a = 1
b = a
b = 2
print(a) --> 1
print(b) --> 2

不是说对地址的引用么,怎么a的输出是1,b的输出是2呢?

这个时候简单讲一下Python中的内存管理。

Python的内存管理,是一种引用计数的方式,之前学过iOS,对ARC很熟悉,Python的这种方式和ARC类似:

当创建一个对象时,该对象的引用计数为1,每次引用,或者是方法参数调用,或是作为容器(列表,字典)内的一个对象,引用计数会加1(脱离方法作用域时将会减1)调用del是会使对象引用计数减1,当引用计数为0时,解释器将通过垃圾回收机制回收那一个对象的空间。

而上面例子中的 b = 2 ,相当于新创建一个对象b,它的值是2,原先b是个简单对象,不可修改,因此对a的引用的b对象被销毁,因此a和b的输出不同,可以这样讲,b = 2 改变了原始对象的“地址”。


copy 和 deepcopy的区别:

copy称为浅拷贝,deepcopy则为深拷贝。

ex:


importcopy

a = [1, 2, 3, ['a', 'b']]
b = copy.copy(a)
c = copy.deepcopy(a)
d = a
a[0] = 0
print(a) --> [0, 2, 3, ['a', 'b']]
print(b) --> [1, 2, 3, ['a', 'b']]
print(c) --> [1, 2, 3, ['a', 'b']]
b[3].append('c')
c[3].append('d')
print(a) --> [0, 2, 3, ['a', 'b', 'c']]
print(b) --> [1, 2, 3, ['a', 'b', 'c']]
print(c) --> [1, 2, 3, ['a', 'b', 'd']]
b.append(5)
c.append('python')
print(a) --> [0, 2, 3, ['a', 'b', 'c']]
print(b) --> [1, 2, 3, ['a', 'b', 'c'], 5]
print(c) --> [1, 2, 3, ['a', 'b', 'd'], 'python']
说明copy是创建一个对象,该对象中的每一个子对象是对原对象中的子对象的引用。因此,原对象为不可修改时,对其操作改了原对象,a和b结果不同;而对其中可修改的对象(例子中是一个列表),操作会影响原对象和现对象,a和b的改变相同。
而deepcopy则是创建一个对象,该对象中的每一个子对象是对原对象中的子对象的拷贝,因此,操作原对象或者是现对象都不会对彼此产生影响。
都是个人的见解,如果不正确的地方,欢迎指出!

以上。


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值