641 字
3 分钟
深拷贝和浅拷贝
2019-02-28

可变和不可变#

可变类型(mutable):列表,字典;value值改变,id值不变; 不可变类型(immutable):数字,字符串,元组;value值改变,id值也随之改变。

赋值,拷贝和深拷贝#

赋值,只是创建一个变量,该变量指向原来内存地址,如下例:

n4 = n3 = n2 = n1 = "123/'Wu'"

"赋值"

浅拷贝,在内存中只额外创建第一层数据,如下图

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n3 = copy.copy(n1)

浅拷贝

深拷贝,在内存中将所有的数据重新创建一份(递归拷贝,排除最后一层,即:python内部对字符串和数字的优化),如下图:

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n4 = copy.deepcopy(n1)

深拷贝

字符串 数字 元祖拷贝#

# 字符串
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

整型数字,浮点型数字和元祖拷贝结果与字符串拷贝结果相同

列表拷贝#

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

单例模式下的类的拷贝#

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深拷贝:值相等,地址不相等

深拷贝和浅拷贝
https://gilgameshzzz.github.io/posts/深拷贝和浅拷贝/
作者
Amadeus
发布于
2019-02-28
许可协议
CC BY-NC-SA 4.0