1 拷贝的定义
-
浅拷贝:不会开辟新的内存空间,只是新增原来对象的引用计数。 -
深拷贝:会开辟新的内存空间,和原来的对象相互独立隔离。
2:常见对象分可变对象和不可变对象
-
可变对象:list,dict -
不可变对象有:int,string,float,tuple
3 拷贝》不可变对象
3.1对不可变对象的深拷贝和浅拷贝都是==浅拷贝(纯不可变对象的拷贝)
示例:
import copy
a = 'Hello World'
print("浅拷贝="*10)
b = copy.copy(a)
print(id(a))
print(id(b))
print(a is b)
print("深拷贝="*10)
b = copy.deepcopy(a)
print(id(a))
print(id(b))
print(a is b)
输出结果为:
浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=
2407672663600
2407672663600
True
深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=
2407672663600
2407672663600
True
3.2对不可变对象的深拷贝和浅拷贝都是==浅拷贝(可变对象内的不可变对象)
import copy
a = ['Hello World']
print("浅拷贝="*10)
b = copy.copy(a)
# 注意这里查看的是是可变对象内的不可变对象的引用
print(id(a[0]))
print(id(b[0]))
print(a[0] is b[0])
print("深拷贝="*10)
b = copy.deepcopy(a)
# 注意这里查看的是是可变对象内的不可变对象的引用
print(id(a[0]))
print(id(b[0]))
print(a[0] is b[0])
输出结果为:
浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=浅拷贝=
2210787577456
2210787577456
True
深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=深拷贝=
2210787577456
2210787577456
True
4 拷贝》可变对象
4.1对【可变对象】的深拷贝和浅拷贝都是==深拷贝
但是如果是浅拷贝:仅限于外层的可变对象拷贝,内嵌的其他不可变对象属于浅拷贝
import copy
a = [1,["小钟",2,3]]
b = copy.copy(a)
print('**浅拷贝源可变对象(1层)**'*5)
print(id(a))
print(id(b))
print(a is b)
print(a,b)
print('**浅拷贝源可变对象(2层)**'*5)
print(id(a[1]))
print(id(b[1]))
print(a[1] is b[1])
print(a[1],b[1])
# b = a #浅拷贝,a,b同时指向一个id,当其中一个修改时,另外一个也会被修改。
print('**浅拷贝源不可变对象(1层)**'*5)
print(id(a[0]))
print(id(b[0]))
print(a[0] is b[0])
print(a[0],b[0])
print('**浅拷贝源不可变对象**(2层)'*5)
print(id(a[1][0]))
print(id(b[1][0]))
print(a[1][0] is b[1][0])
print(a[1][0],b[1][0])
print("修改不可变对象**(2层)")
a[1][0] = "小钟同学中彩票了--1!"
b[1][0] = "小钟同学中彩票了--2!"
print(id(a[1][0]))
print(id(b[1][0]))
print(a[1][0] is b[1][0])
print(a[1][0],b[1][0])
print("输出拷贝后对象")
print(a,b)
输出结果:
**浅拷贝源可变对象(1层)****浅拷贝源可变对象(1层)****浅拷贝源可变对象(1层)****浅拷贝源可变对象(1层)****浅拷贝源可变对象(1层)**
2008718632264
2008718630984
False
[1, ['小钟', 2, 3]] [1, ['小钟', 2, 3]]
**浅拷贝源可变对象(2层)****浅拷贝源可变对象(2层)****浅拷贝源可变对象(2层)****浅拷贝源可变对象(2层)****浅拷贝源可变对象(2层)**
2008718442248
2008718442248
True
['小钟', 2, 3] ['小钟', 2, 3]
**浅拷贝源不可变对象(1层)****浅拷贝源不可变对象(1层)****浅拷贝源不可变对象(1层)****浅拷贝源不可变对象(1层)****浅拷贝源不可变对象(1层)**
140711692460880
140711692460880
True
1 1
**浅拷贝源不可变对象**(2层)**浅拷贝源不可变对象**(2层)**浅拷贝源不可变对象**(2层)**浅拷贝源不可变对象**(2层)**浅拷贝源不可变对象**(2层)
2008716786128
2008716786128
True
小钟 小钟
修改不可变对象**(2层)
2008717747784
2008717747784
True
小钟同学中彩票了--2! 小钟同学中彩票了--2!
输出拷贝后对象
[1, ['小钟同学中彩票了--2!', 2, 3]] [1, ['小钟同学中彩票了--2!', 2, 3]]
说明:
浅拷贝:
对不可变对象的拷贝,永远是浅拷贝,及时不会新增新的内存的空间 对可变对象的拷贝,永远是对于外层的可变对象来说会开辟新的内存空间,但是对于内存的可变对象来说是属于浅拷贝(如果浅拷贝对象是一个可变的对象,那么拷贝新的对象,会开新空间,但是内部【其他可变和不可变】都是是原来的对象,不变)
4.2对【可变对象】的深拷贝都是深拷贝(如果内部是不可变对象)
但是如果是深拷贝的内部也好,外部也好都是属于浅拷贝
import copy
a = [1,["小钟",2,3]]
b = copy.deepcopy(a)
print('**深拷贝源可变对象(1层)**'*5)
print(id(a))
print(id(b))
print(a is b)
print(a,b)
print('**深拷贝源可变对象(2层)**'*5)
print(id(a[1]))
print(id(b[1]))
print(a[1] is b[1])
print(a[1],b[1])
# b = a #深拷贝,a,b同时指向一个id,当其中一个修改时,另外一个也会被修改。
print('**深拷贝源不可变对象(1层)**'*5)
print(id(a[0]))
print(id(b[0]))
print(a[0] is b[0])
print(a[0],b[0])
print('**深拷贝源不可变对象**(2层)'*5)
print(id(a[1][0]))
print(id(b[1][0]))
print(a[1][0] is b[1][0])
print(a[1][0],b[1][0])
print("修改不可变对象**(2层)")
a[1][0] = "小钟同学中彩票了--1!"
b[1][0] = "小钟同学中彩票了--2!"
print(id(a[1][0]))
print(id(b[1][0]))
print(a[1][0] is b[1][0])
print(a[1][0],b[1][0])
print("输出拷贝后对象")
print(a,b)
输出结果:
**深拷贝源可变对象(1层)****深拷贝源可变对象(1层)****深拷贝源可变对象(1层)****深拷贝源可变对象(1层)****深拷贝源可变对象(1层)**
2379749762504
2379749761288
False
[1, ['小钟', 2, 3]] [1, ['小钟', 2, 3]]
**深拷贝源可变对象(2层)****深拷贝源可变对象(2层)****深拷贝源可变对象(2层)****深拷贝源可变对象(2层)****深拷贝源可变对象(2层)**
2379749453704
2379749792008
False
['小钟', 2, 3] ['小钟', 2, 3]
**深拷贝源不可变对象(1层)****深拷贝源不可变对象(1层)****深拷贝源不可变对象(1层)****深拷贝源不可变对象(1层)****深拷贝源不可变对象(1层)**
140711688528720
140711688528720
True
1 1
**深拷贝源不可变对象**(2层)**深拷贝源不可变对象**(2层)**深拷贝源不可变对象**(2层)**深拷贝源不可变对象**(2层)**深拷贝源不可变对象**(2层)
2379748769352
2379748769352
True
小钟 小钟
修改不可变对象**(2层)
2379744094704
2379748763208
False
小钟同学中彩票了--1! 小钟同学中彩票了--2!
输出拷贝后对象
[1, ['小钟同学中彩票了--1!', 2, 3]] [1, ['小钟同学中彩票了--2!', 2, 3]]
说明:
深拷贝:
对不可变对象的拷贝,永远是浅拷贝,及时不会新增新的内存的空间。 对可变对象的拷贝,永远不算内外的可变对象都会新增开辟新的内存空间。
总结
-
深拷贝:对于所有可变对象都是深拷贝(不分内外对象),开辟新内存空间 -
浅拷贝:如果包含对象是一个可变,也会开辟新内存空间(分内外对象),但仅限于最外层的进行深拷贝,内存不管是可变和不可变都是属于浅拷贝。
转载请注明:XAMPP中文组官网 » python面向对象编程篇-深拷贝和浅拷贝