赋值

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

>>> num2=num1 
>>> str2=str1 
>>> dict2= dict1

数字和字符串赋值

 

 

python中深浅拷呗 python深浅拷贝原理_字符串

    

字典、列表、元组的赋值

python中深浅拷呗 python深浅拷贝原理_深浅拷贝_02

 

深浅拷贝 

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

 

数字和字符串的深浅拷贝

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

 

python中深浅拷呗 python深浅拷贝原理_字符串

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

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

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

python中深浅拷呗 python深浅拷贝原理_深浅拷贝_04

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

 

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

python中深浅拷呗 python深浅拷贝原理_bc_05

 

 

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