Python 深浅拷贝

浅拷贝:创建一个新的对象,但不复制对象内部的子对象。新对象中的子对象仍然引用原对象中的子对象,对新对象的修改可能会影响原对象。

深拷贝:创建一个新的对象,同时递归地拷贝原对象内部的所有子对象。新对象与原对象完全独立,修改新对象不会影响原对象。

深拷贝的实现和示例

# 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]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩未零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值