python 赋值, 浅拷贝,和深拷贝的区别
- 赋值
=
是创建了对象的一个新引用,将原有的数据对象添加一个标签. 如果原有数据对象是不可变的(基础类型),当新的对象被创建时,就会开辟新的内存位置. 如果原有数据对象是可变的(list,dict等),就会在原有对象上进行修改.
a=1
b=a
a=2
b=? #1
#---
a={'a': 1}
b=a
b['b']=2
a=? # {'a': 1, 'b': 2}
-
浅拷贝
copy.copy()
只拷贝对象本身,不会拷贝其内部的嵌套对象. 复杂子对象的保存方式是作为引用方式存储的,所以修改浅拷贝的值和原来的值都可以改变复杂子对象的值. -
深拷贝
copy.deepcopy()
会拷贝对象本身及其所有的嵌套对象. 深拷贝将被复制对象完全再复制一遍作为独立的新个体单独存在.
import copy
a=[1,2,3,4,['a','b']]
b = a
c = copy.copy(a)
d = copy.deepcopy((a))
print('a init = ' , a)
a.append(5)
a[4].append('c')
a[0] = 66
print('a final = ' , a)
print('b = ' , b)
print('c = ' , c)
print('d = ' , d)
# 输出
# a init = [1, 2, 3, 4, ['a', 'b']]
# a final = [66, 2, 3, 4, ['a', 'b', 'c'], 5]
# b = [66, 2, 3, 4, ['a', 'b', 'c'], 5] , b会完全随着a列表的改变而改变.
# c = [1, 2, 3, 4, ['a', 'b', 'c']] , a内部对象的改变,会影响浅拷贝对象C的值
# d = [1, 2, 3, 4, ['a', 'b']] , a内部对象的改变,不影响深拷贝对象d的值
总结
如果一个对象是不可变对象例如数值,字符串,元组
, 那么对它进行赋值和浅拷贝的效果一致,修改一个对象的只不会影响另一个对象的值,应为修改对象时会重新开辟空间.
如果一个对象是可变对象且无嵌套复杂子对象, 例如普通字典,列表
- 对它进行赋值后,修改一个对象的值会影响另一个对象的值.
- 对它进行浅拷贝,修改一个对象的值不会影响另一个对象的值.
如果一个对象是可变对象且嵌套了复杂子对象, 对它进行浅拷贝后:
- 如果改变其复杂子对象的值,那么会影响浅拷贝的另一个对象.
- 如果改变的不是复杂子对象的值,那么不会影响浅拷贝的另一个对象.