Python深拷贝与浅拷贝的区别(一文看懂)


很多人在学python的过程中往往会混淆深拷贝与浅拷贝的概念,深拷贝是对于对象的完全复制,这个好理解。很多人对浅拷贝理解为windows的快捷方式,其实也不尽然…下面的文字将会让你彻底理解他们之间的关系。

先从一道面试题开始:
写出下列代码运行结果:

import copy  
a = [1, 2, 3, 4, ['a', 'b']] 
b = a 
c = copy.copy(a) 
d = copy.deepcopy(a) 
a.append(5)             [1, 2, 3, 4, ['a', 'b'], 5] 
a[4].append('c')        ['a', 'b', 'c']
print 'a = ', a   		[1, 2, 3, 4, ['a', 'b', 'c'], 5]
print 'b = ', b  		[1, 2, 3, 4, ['a', 'b', 'c'], 5]
print 'c = ', c  		[1, 2, 3, 4, ['a', 'b', 'c']]
print 'd = ', d  		[1, 2, 3, 4, ['a', 'b']] 

很多人不理解c的输出结果,这正是因为没有深刻理解浅拷贝而容易走进的误区。


先说结论,让我们来一起按图索骥:

  • 浅拷贝:对顶层对象引用的拷贝。
  • 深拷贝:对一个对象所有层次的拷贝(递归)。【即按照原来的样子在内存中申请空间另外创建一份,与拷贝对象没有任何关系】

示例:

>>> import copy
>>> a = [1,2]
>>> b = [3,4]
>>> c = [a,b]
>>> d = c  # d = c相当于增加了对 对象[a,b] 的引用计数
>>> e = copy.copy(c) # e是对c的浅拷贝,即对c顶层对象的拷贝

d = c 与 e = copy.copy(c)的区别?

>>> id(c),id(d),id(e)
(140089296095856, 140089296095856, 140089296096144)

可以看出cd指向同一块内存,e为另外一块内存区域,所以d=c仅仅是增加了[a,b]的引用计数,而e = copy.copy(c)使系统在内存中另外申请一块内存,用于存放[a,b]的值.

针对可变与不可变类型的浅拷贝

  • 可变类型mutable:列表、字典
>>> import copy
>>> a = [1,2]
>>> b = copy.copy(a)
>>> id(a)
139729228940856
>>> id(b) 
139729228503808

浅拷贝对于可变类型而言:在内存重新划分一块区域,其中保存对顶层对象的引用

  • 不可变类型immutable:数字、字符串、元组
>>> import copy
>>> a = "amuqiao"
>>> b = copy.copy(a)
>>> id(a)
140663661215344
>>> id(b)
140663661215344

浅拷贝对于不可变类型而言是对被拷贝对象的引用

带着结论回顾第一题

import copy  
a = [1, 2, 3, 4, ['a', 'b']] 
b = a 
c = copy.copy(a) 
d = copy.deepcopy(a) 
a.append(5)             [1, 2, 3, 4, ['a', 'b'], 5] 
a[4].append('c')        ['a', 'b', 'c']
print 'a = ', a   		[1, 2, 3, 4, ['a', 'b', 'c'], 5]
print 'b = ', b  		[1, 2, 3, 4, ['a', 'b', 'c'], 5]
# 可以得到两点:1.c是对a的浅拷贝;2.a是可变类型,即只保存对a顶层对象的引用。
# 换句话说:在内存中重新划分一块内存,用于保存对a顶层对象的引用,此时id(a)不等于id(c),
# 当a.append(5)的时候,c中保存的"a的顶层对象的引用"的值并没有改变,所以c不变
# 当a[4].append('c')的时候,c中保存的"a的顶层对象的引用"的值['a', 'b']变成了
# ['a', 'b','c'],所以c也改变了
print 'c = ', c  		[1, 2, 3, 4, ['a', 'b', 'c']]
print 'd = ', d  		[1, 2, 3, 4, ['a', 'b']] 

深拷贝

对一个对象所有层次的拷贝(递归)。【即按照原来的样子在内存中申请空间另外创建一份,与拷贝对象没有任何关系】

参考链接:
1.Python中的copy和deepcopy
2.理解python可变类型vs不可变类型,深拷贝vs浅拷贝


文章作者: LuffyKing
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LuffyKing !
  目录