赋值就是对象的引用,想都不要想。
浅拷贝:
方式有3种:完全切片、工厂函数如list() dict()、copy模块的copy()
效果:产生一个与与原对象同类型的新的对象,不可变元素仍是引用,但赋值时可以重新分配内存而改变;可变元素也是引用,给其下一级元素赋值时不分配内存而仍指向原对象的元素,给这个可变元素本身赋值时重新分配内存并改变。
有代码为证:
>>> a = ['name',['save',100]]
>>> import copy
>>> [id(x) for x in a]
[3071986464, 140622924]
>>> c = copy.copy(a)
>>> [id(x) for x in c]
[3071986464, 140622924]
>>> c[0] = 'mm'
>>> [id(x) for x in c]
[140796544, 140622924]
>>> c[1][0] = 'mm'
>>> [id(x) for x in c]
[140796544, 140622924]
>>> c[1] = ['mm',12]
>>> [id(x) for x in c]
[140796544, 140796812]
深拷贝:
方法只有一种:copy模块的depcopy()
效果:产生一个与与原对象同类型的新的对象,不可变元素仍是引用,但赋值时可以重新分配内存而改变;可变元素却不是引用而已经分配内存,给下一级元素赋值时改变自己的内存区,给这个可变元素本身赋值时再重新分配内存并改变。
有代码为证:
>>> a = ['name',['save',100]]
>>> import copy
>>> b = copy.deepcopy(a)
>>> [id(x) for x in a]
[3071716128, 163115532]
>>> [id(x) for x in b]
[3071716128, 163118348]
>>> b[0] = 'mm'
>>> [id(x) for x in b]
[163278720, 163118348]
>>> b[1][1] = 200
>>> [id(x) for x in b]
[163278720, 163118348]
>>> b[1] = 200
>>> [id(x) for x in b]
[163278720, 137224048]
对于非容器类型,不管是单个元素还是组成列表,浅拷贝与深拷贝效果相同。
效果:产生一个与与原对象同类型的新的对象,不可变元素仍是引用,但赋值时可以重新分配内存而改变。
有组成列表的例子为证:
>>> a = ['name',12]
>>> b = copy.copy(a)
>>> [id(x) for x in a]
[3071716128, 137221040]
>>> [id(x) for x in b]
[3071716128, 137221040]
>>> b[0] = 'mm'
>>> [id(x) for x in b]
[165786144, 137221040]
>>> b[1] = 'mm'
>>> [id(x) for x in b]
[165786144, 165786144]
>>> b[1] = 123
>>> [id(x) for x in b]
[165786144, 137222816]
>>> b = copy.deepcopy(a)
>>> [id(x) for x in b]
[3071716128, 137221040]
>>> b[0] = 'mm'
>>> [id(x) for x in b]
[165786144, 137221040]
>>> b[1] = 'mm'
>>> [id(x) for x in b]
[165786144, 165786144]
>>> b[1] = 123
>>> [id(x) for x in b]
[165786144, 137222816]