可变和不可变
可变类型(mutable):列表,字典;value值改变,id值不变;
不可变类型(unmutable):数字,字符串,元组;value值改变,id值也随之改变。
赋值,拷贝和深拷贝
赋值,只是创建一个变量,该变量指向原来内存地址,如下例:
1
| n4 = n3 = n2 = n1 = "123/'Wu'"
|
浅拷贝,在内存中只额外创建第一层数据,如下图
1 2 3
| import copy n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]} n3 = copy.copy(n1)
|
深拷贝,在内存中将所有的数据重新创建一份(递归拷贝,排除最后一层,即:python内部对字符串和数字的优化),如下图:
1 2 3
| import copy n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]} n4 = copy.deepcopy(n1)
|
字符串 数字 元祖拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| a = 'copytest' b = copy.copy(a) c = copy.deepcopy(a)
if __name__ == '__main__': print(a, id(a)) print(b, id(b)) print(c, id(c))
copytest 49797384 copytest 49797384 copytest 49797384
|
整型数字,浮点型数字和元祖拷贝结果与字符串拷贝结果相同
列表拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13
| a = [1, 2, 5, [1, 3, 5]] b = copy.copy(a) c = copy.deepcopy(a) b[-1].pop()
if __name__ == '__main__': print(a, id(a)) print(b, id(b)) print(c, id(c))
[1, 2, 5, [1, 3]] 50059904 [1, 2, 5, [1, 3]] 50007496 [1, 2, 5, [1, 3, 5]] 50059584
|
单例模式下的类的拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| def singleton(cls): instances = {}
@wraps(cls) def get_instances(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls]
return get_instances
@singleton class Animal(): def __init__(self, name): self.name = name
def aloud(self): print(self.name + '123568')
a = Animal('cat') b = copy.copy(a) c = copy.deepcopy(a) c.name = 'dog' d = Animal('adas')
if __name__ == '__main__': print(a, id(a)) a.aloud() print(b, id(b)) b.aloud() print(c, id(c)) c.aloud() print(d, id(d)) d.aloud()
<__main__.Animal object at 0x02F67DD0> 49708496 cat123568 <__main__.Animal object at 0x02FACD90> 49991056 cat123568 <__main__.Animal object at 0x02FACAD0> 49990352 dog123568 <__main__.Animal object at 0x02F67DD0> 49708496 cat123568
|
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
总结
1,深浅拷贝都是对源对象的复制,占用不同的内存空间。
2,不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
3,可变类型:
=浅拷贝: 值相等,地址相等
copy浅拷贝:值相等,地址不相等
deepcopy深拷贝:值相等,地址不相等