Python 对象 之 深浅拷贝原理

赋值

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

>>> num2=num1 

>>> str2=str1 

>>> dict2= dict1

数字和字符串赋值

 

     

字典、列表、元组的赋值

 

深浅拷贝 

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

copy.copy() : 浅拷贝

copy.deepcopy() : 深拷贝

 

数字和字符串的深浅拷贝

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

 

>>> import copy  

>>> 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]}

 

posted @ 2017-05-21 10:00  bobo0609  Views(558)  Comments(0Edit  收藏  举报