python深拷贝实现原理_Python 对象 之 深浅拷贝原理

赋值

对于任何数据类型,赋值都是创建一个变量,然后对原内存中对象的引用。

>>> num2=num1

>>> str2=str1

>>> dict2= dict1

数字和字符串赋值

字典、列表、元组的赋值

深浅拷贝

import copy  #导入copy模块,深浅拷贝的原理内部通过copy模块实现

copy.copy() : 浅拷贝

copy.deepcopy() : 深拷贝

数字和字符串的深浅拷贝

对于 数字 和 字符串 而言,浅拷贝和深拷贝都是复制对象的内存地址,并没有在内存开辟另外一块内存空间创建新的对象,所以并没有意义( 可以把数字和字符串理解成数据类型的最小单元)。

>>> importcopy>>> num1=123

>>> num2=copy.copy(num1)>>> num3=copy.deepcopy(num1)>>> print(id(num1),id(num2),id(num3))140572605875360 140572605875360 140572605875360

>>> str1='abc'>>> str2=copy.copy(str1)>>> str3=copy.deepcopy(str1)>>> print(id(str1),id(str2),id(str3))140572607345752 140572607345752 140572607345752

字典、元祖、列表的深浅拷贝

浅拷贝:在内存中只额外创建第一层数据

>>> dc1={'k1':123,'k2':'abc','k3':[456,'def']}>>> dc2=copy.copy(dc1)

>>> print(id(dc1['k3']),id(dc2['k3']))# 可以看到两个字典的k3指向不同内存地址

140572345367048 140572345367048

>>> dc2['k3'][1]='xyz'

>>> print(dc1,dc2) #可以看到修改了dc2中的列表,dc1中的列表也跟着变了

{'k1': 123, 'k2': 'abc', 'k3': [456, 'xyz']} {'k1': 123, 'k2': 'abc', 'k3': [456, 'xyz']}

深拷贝:在内存中将除了数字和字符串外的所有数据重新创建一份;

>>> dc1={'k1':123,'k2':'abc','k3':[456,'def']}>>> dc2=copy.deepcopy(dc1)>>> print(id(dc1['k3']),id(dc2['k3'])) # 可以看到两个字典的指向不同的内存地址140572359070024 140572345368648

>>> dc2['k3'][1]='xyz'

>>> print(dc1,dc2)#可以看到修改了dc2中的列表,dc1中的列表依然没变

{'k1': 123, 'k2': 'abc', 'k3': [456, 'def']} {'k1': 123, 'k2': 'abc', 'k3': [456, 'xyz']}

深浅拷贝的应用举例

例如有一批机器应用一个监控模板,当cpu> 80%,mem > 80%, disk > 80% 时触发告警,用字典表示如下:

dic = {

'cpu':[80,],

'mem':[80,],

'disk':[80,]

}

有另外一批机器需要应用另外一个监控模板,当cpu> 50%,mem > 80%, disk > 80% 时触发告警,可以对原dic作深拷贝:

newdic=copy.deepcopy(dic)

newdic['cpu'][0]=50

print(dic,newdic)  # 可以看到对新模板内列表元素的修改,不会影响到原模板

{'cpu': [80], 'mem': [80], 'disk': [80]} {'cpu': [50], 'mem': [80], 'disk': [80]}


版权声明:本文为weixin_32154667原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。