浅拷贝:创建一个新的对象,但不复制对象内部的子对象。新对象中的子对象仍然引用原对象中的子对象,对新对象的修改可能会影响原对象。
深拷贝:创建一个新的对象,同时递归地拷贝原对象内部的所有子对象。新对象与原对象完全独立,修改新对象不会影响原对象。
深拷贝的实现和示例
# Python的copy模块提供了copy函数和deepcopy函数,分别用于实现浅拷贝和深拷贝。
import copy
#第一种:如果字典只有顶级对象(没有带嵌套)
d = {'name':'jack', 'age':'18'}
c1 = copy.copy(d) #浅拷贝
c2 = copy.deepcopy(d) #深拷贝
print(id(d), id(c1), id(c2)) # 2782749422336 2782749422528 2782749814912 三个不同对象
d['age'] = 20
print(d, c1, c2, sep="\n")
# {'name': 'jack', 'age': 20}
# {'name': 'jack', 'age': '18'}
# {'name': 'jack', 'age': '18'}
源对象修改值的时候,深浅拷贝的对象值没有改变。
import copy
# 第二种,字典中有嵌套
d = {'name': {'first': 'liu', 'last': 'guan'}, 'job': ['food', 'deops']}
c1 = copy.copy(d)
c2 = copy.deepcopy(d)
print(id(d), id(c1), id(c2)) # 2490190820288 2490190820352 2490197992256
d['job'][0] = 'zhang'
print(d, c1, c2, sep="\n")
# {'name': {'first': 'liu', 'last': 'guan'}, 'job': ['zhang', 'deops']}
# {'name': {'first': 'liu', 'last': 'guan'}, 'job': ['zhang', 'deops']}
# {'name': {'first': 'liu', 'last': 'guan'}, 'job': ['food', 'deops']}
源对象修改值的时候,浅拷贝的值跟着改变,深拷贝的值没变。
使用切片操作进行浅拷贝
import copy
# 创建一个列表
lst1 = [1, 3, [5, 7], 9]
# 使用copy.deepcopy进行深拷贝
Deep_lst = copy.deepcopy(lst1)
print("原列表:", lst1)
print("深拷贝列表:", Deep_lst)
# 修改深拷贝列表中的嵌套列表
Deep_lst[2][0] = 99
print("修改后原列表:", lst1)
print("修改后深拷贝列表:", Deep_lst)
#原列表: [1, 3, [5, 7], 9]
#深拷贝列表: [1, 3, [5, 7], 9]
#修改后原列表: [1, 3, [5, 7], 9]
#修改后深拷贝列表: [1, 3, [99, 7], 9]
深拷贝后的对象与原对象完全独立,因此修改深拷贝对象中的嵌套对象不会影响原对象。
拷贝自定义对象
可以通过实现 __copy__和__deepcopy__ 方法来定制拷贝行为。
实现自定义浅拷贝
import copy
class CustomObject:
def __init__(self, value):
self.value = value
def __copy__(self):
print("开始执行自定义浅拷贝")
return CustomObject(self.value)
original_obj = CustomObject(10)
new_obj = copy.copy(original_obj)
print("原对象:", original_obj)
print("浅拷贝对象:", new_obj)
# 开始执行自定义浅拷贝
# 原对象: <__main__.CustomObject object at 0x000001E2B072CEB0>
# 浅拷贝对象: <__main__.CustomObject object at 0x000001E2B072CDF0>
实现自定义深拷贝
import copy
class CustomObject:
def __init__(self, value):
self.value = value
def __deepcopy__(self, memo):
print("========开始执行自定义深拷贝=========")
return CustomObject(copy.deepcopy(self.value, memo))
original_obj = CustomObject(1)
deep_new_obj = copy.deepcopy(original_obj)
print("原对象:", original_obj)
print("深拷贝对象:", deep_new_obj)
# ========开始执行自定义深拷贝=========
# 原对象: <__main__.CustomObject object at 0x000002165D7ECEB0>
# 深拷贝对象: <__main__.CustomObject object at 0x000002165D7ECDF0>
注意事项
对于不可变对象,如整数、字符串和元组,浅拷贝和深拷贝的结果是相同的,因为不可变对象的内容不会改变。
import copy
num = 3
copy_num = copy.copy(num)
deep_copy_num = copy.deepcopy(num)
print("原对象:", num)
print("浅拷贝对象:", copy_num)
print("深拷贝对象:", deep_copy_num)
# 原对象: 3
# 浅拷贝对象: 3
# 深拷贝对象: 3
循环引用
在处理复杂数据结构时,可能会遇到循环引用的情况。深拷贝能够正确处理循环引用,而浅拷贝可能会导致无限循环。
import copy
a = [1, 2]
b = [a, 4, 5]
a.append(b)
deep_copy_a = copy.deepcopy(a)
print("深拷贝对象:", deep_copy_a)
#深拷贝对象: [1, 2, [[...], 4, 5]]