Python基础教程

011_深拷贝与浅拷贝

深拷贝与浅拷贝

深拷贝与浅拷贝的理解

拷贝就是复制,复制就是变量赋值。变量分为简单变量和复合变量。对于简单变量,拷贝就是常规变量间赋值;对于复合变量,拷贝分为浅拷贝和深拷贝。也就是说,简单变量不分浅拷贝和深拷贝,它们拷贝的结果是一样的。

浅拷贝,产生一个新的复合变量(对象),复制了原复合变量的外层对象和子对象的引用(引用与子对象有关联)。

深拷贝,产生一个新的复合变量(对象),复制了原复合变量的外层和子对象的副本(副本与子对象无关联)。

Python标准库中提供了copy模块,里面copy.copy()和copy.deepcopy()分别用于变量(对象)的浅拷贝和深拷贝。

另外,Python中不可变对象的拷贝不会创建新对象,可变对象的拷贝会创建新对象。

简单对象int类型(并且不可变对象)的拷贝,不创建新对象

import copy

a = 12
b= a                  # 赋值拷贝
c = copy.copy(a)      # 浅拷贝
d = copy.deepcopy(a)  # 深拷贝

print(id(a))          # 140705177314032
print(id(b))          # 140705177314032
print(id(c))          # 140705177314032
print(id(d))          # 140705177314032

简单对象str类型(并且不可变对象)的拷贝,不创建新对象

import copy

a = "abc"
b= a                  # 赋值拷贝
c = copy.copy(a)      # 浅拷贝
d = copy.deepcopy(a)  # 深拷贝

print(id(a))          # 1888525808240
print(id(b))          # 1888525808240
print(id(c))          # 1888525808240
print(id(d))          # 1888525808240

简单对象list类型(可变对象)的拷贝,创建新对象

import copy

a = [12,"abc"]
b= a                  # 赋值拷贝
c = copy.copy(a)      # 浅拷贝
d = copy.deepcopy(a)  # 深拷贝

print(id(a))          # 1463420727432
print(id(b))          # 1463420727432    可变对象的对象地址赋值
print(id(c))          # 1463423010952    新对象
print(id(d))          # 1463423189384    新对象

复合对象的深拷贝与浅拷贝

示例中的复合对象是list嵌套对象。

import copy

a = [12,"abc",[1,2,3]]
b= a                  # 赋值拷贝
c = copy.copy(a)      # 浅拷贝
d = copy.deepcopy(a)  # 深拷贝

print(id(a))       # 1764972890120
print(id(b))       # 1764972890120    可变对象的对象地址赋值
print(id(c))       # 1764973061640    新对象
print(id(d))       # 1764972968136    新对象

print("----------------------------------------------")

print(a)           # [12, 'abc', [1, 2, 3]]    复合对象
print(a[2])        # [1, 2, 3]                 子对象
print(b)           # [12, 'abc', [1, 2, 3]]    浅拷贝对象
print(c)           # [12, 'abc', [1, 2, 3]]    浅拷贝对象
print(d)           # [12, 'abc', [1, 2, 3]]    深拷贝对象

print(id(a[2]))    # 1764970855560
print(id(b[2]))    # 1764970855560
print(id(c[2]))    # 1764970855560   浅拷贝中子对象与原复合对象地址相同,是引用
print(id(d[2]))    # 1764973081928   深拷贝中子对象与原复合对象地址不同,是副本

更多相关内容可以参考标准库讲解。

https://docs.python.org/zh-cn/3/library/copy.html

这篇文章对您有用吗?

我们要如何帮助您?