python浅拷贝与深拷贝

可以 Python的拷贝,浅拷贝,深拷贝

赋值,浅拷贝,深拷贝在开发中常会用到,但是[拷贝|浅拷贝|深拷贝]只针对可变数据类型,一起看看他们之间的区别吧!


一.赋值

  • 其实就是对象的引用(别名)。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
>>> # a, b内存地址相同
>>> # a, b的变化完全同步

>>> a = {1: [1,2,3]}
>>> b = a
>>> print(b) #{1: [1, 2, 3]}

>>> a[1] = [1,2,3,4] #更改a
>>> print(a) #{1: [1, 2, 3, 4]}
>>> print(b) #{1: [1, 2, 3, 4]} # b同步改变

>>> b[1] = [1,2,3,4,5] #更改b
>>> print(a) #{1: [1, 2, 3, 4, 5]} #a也同步改变
>>> print(b) #{1: [1, 2, 3, 4, 5]}

image

二.浅拷贝

  • 拷贝父对象,不会拷贝对象的内部的子对象。
>>> # a, b的内存地址不同,a, b的子对象的内存地址相同
>>> # a, b的子对象的变化同步,a, b的其他变化不同步

>>> import copy
>>> a = {1: [1, 2, 3]}
>>> b = copy.copy(a)

>>> id(a), id(b) #a, b的内存地址不同
(4413393008, 4414925848)
>>> id(a[1]), id(b[1]) #a, b的子对象的内存地址相同
(4414889544, 4414889544)

>>> a[1].append(4) #改变a子对象值
>>> print(a) # {1: [1, 2, 3, 4]}
>>> print(b) # {1: [1, 2, 3, 4]} # b中子对象的值跟着变了

>>> a[2] = [7, 8] # 改变a外层对象
>>> print(a) # {1: [1, 2, 3, 4], 2: [7, 8]}
>>> print(b) # {1: [1, 2, 3, 4]} # b外层对象不跟着变

image

三.深拷贝

  • 完全拷贝了父对象及其子对象
>>> # a, b内存地址不同,a, b子对象的内存地址也不同
>>> # a, b的变化完全无关

>>> import copy
>>> a = {1: [1, 2, 3]}
>>> b = copy.deepcopy(a)

>>> id(a), id(b) #  a, b内存地址不同
(4413393008, 4414925920)
>>> id(a[1]), id(b[1]) # a, b子对象的内存地址也不同
(4414889736, 4414934344)

>>> a[2] = [7, 8] #改变a外层对象, a, b的变化完全无关
>>> print(a) # {1: [1, 2, 3], 2: [7, 8]}
>>> print(b) # {1: [1, 2, 3]}

>>> b[1].append(4)# 改变b内层子对象,a, b的变化完全无关
>>> print(a) # {1: [1, 2, 3], 2: [7, 8]}
>>> print(b) # {1: [1, 2, 3]}

image


结论

  • 深浅拷贝都是对源对象的复制,占用不同的内存空间
  • 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象
  • 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝
  • 序列对象的切片其实是浅拷贝,即只拷贝顶级的对象
posted @ 2022-04-30 11:59  大切切  阅读(19)  评论(0编辑  收藏  举报