[随笔重写] Python3 的深拷贝与浅拷贝

Posted YorkFish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[随笔重写] Python3 的深拷贝与浅拷贝相关的知识,希望对你有一定的参考价值。

1. Python3 关于深浅拷贝的官方文档

2. 先说结论

  • 深拷贝与浅拷贝是对复合对象而言的
  • 深拷贝会构造一个新的复合对象,然后递归地将在原始对象中所有元素的副本对应地写入新复合对象中
  • 浅拷贝会构造一个新的复合对象,然后(在允许的前提下)向其中写入对原始对象的引用

3. 开始分析

  • 复合对象:包含其他对象的对象,如列表、类实例等
  • 模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口、数组等不能被拷贝
  • 示例
# 例1

import copy                         # 导入 copy 模块

list1_1 = [0, 1, 2, [‘a‘, ‘b‘]]
list1_2 = list1_1                   # 赋值
list1_3 = list1_1.copy()            # 浅拷贝;同 list1_3 = list1_1[:]
list1_4 = copy.copy(list1_1)        # 浅拷贝
list1_5 = copy.deepcopy(list1_1)    # 深拷贝

# 打印出拷贝后的 list1_1 ~ list1_5
print("list1_1 =", list1_1)
print("list1_2 =", list1_2)
print("list1_3 =", list1_3)
print("list1_4 =", list1_4)
print("list1_5 =", list1_5)
print(‘-‘*40)                       # 分割线

list1_1.append(4)                   # 在 list1_1 末尾添加一个元素 4
list1_1[3].append(‘c‘)              # 向 list1_1 中内嵌的列表末尾添加一个元素 ‘c‘

# 打印出更改后的 list1_1 ~ list1_5
print("list1_1‘ =", list1_1)
print("list1_2‘ =", list1_2)
print("list1_3‘ =", list1_3)
print("list1_4‘ =", list1_4)
print("list1_5‘ =", list1_5)

>>>

list1_1 = [0, 1, 2, [‘a‘, ‘b‘]]
list1_2 = [0, 1, 2, [‘a‘, ‘b‘]]
list1_3 = [0, 1, 2, [‘a‘, ‘b‘]]
list1_4 = [0, 1, 2, [‘a‘, ‘b‘]]
list1_5 = [0, 1, 2, [‘a‘, ‘b‘]]
----------------------------------------
list1_1‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘], 4]
list1_2‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘], 4]
list1_3‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘]]
list1_4‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘]]
list1_5‘ = [0, 1, 2, [‘a‘, ‘b‘]]


  • 由例1 可看出
    1. 简单的赋值只是将引用传给新对象,新旧对象除变量名外毫无区别
    2. 原对象中非第一层的可变元素发生变化时,浅拷贝的新对象中的对应元素同步变化
    3. 深拷贝的新对象是一个真正的副本,不随原对象的改变而改变
  • 补充
    1. 拷贝后的新对象占用新的空间,但其内部的元素指向原对象内部对应元素的地址
    2. 原对象中非第一层的不可变元素重新生成时,浅拷贝的新对象中的对应元素保持不变











以上是关于[随笔重写] Python3 的深拷贝与浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

Cpp下的深拷贝与浅拷贝探究

数组的深拷贝与浅拷贝

数组的深拷贝与浅拷贝

python的深拷贝与浅拷贝

Python中的深拷贝与浅拷贝

js中的深拷贝与浅拷贝