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则是创建一个对象,该对象中的每一个子对象是对原对象中的子对象的拷贝,因此,操作原对象或者是现对象都不会对彼此产生影响。都是个人的见解,如果不正确的地方,欢迎指出!以上。
本文深入探讨Python中变量引用的工作原理,特别是针对复杂数据结构的引用行为,并对比了浅拷贝与深拷贝的区别。
539

被折叠的 条评论
为什么被折叠?



