如何在Python的deepcopy操作中排除特定对象引用不被复制?
解决Deepcopy时保留关联对象引用的问题
我懂你的需求——想要对Foo实例做深度复制,但让linked_to属性跳过深度复制,直接保留对原对象的引用。默认的deepcopy会递归复制所有属性,所以才会导致你的a3.linked_to指向了a1的副本,而不是原对象,最终修改操作没影响到原实例。
解决方案:自定义__deepcopy__方法
Python的copy模块允许我们通过实现类的__deepcopy__方法来定制深度复制的行为。我们可以在这个方法里手动控制哪些属性要深度复制,哪些直接保留引用。
修改你的代码如下:
from copy import deepcopy class Foo: def __init__(self, content, linked_to): self.content = content self.linked_to = linked_to def __deepcopy__(self, memo): # 对content做深度复制,linked_to直接沿用原对象引用 new_instance = Foo(deepcopy(self.content, memo), self.linked_to) # 将新实例存入memo字典,避免循环引用引发的无限递归 memo[id(self)] = new_instance return new_instance a1 = Foo([[1,2],[3,4]], None) a2 = Foo([[5,6],[7,8]], a1) a3 = deepcopy(a2) # 现在修改a3.linked_to的content会直接作用于原a1 a3.linked_to.content.append([9,10]) print(a1.content) # 输出: [[1,2],[3,4], [9,10]]
代码说明
__deepcopy__方法的memo参数是一个字典,用来记录已经复制过的对象,防止出现循环引用时无限递归复制。- 我们对
content属性正常调用deepcopy并传入memo,保证它的深度复制行为符合预期。 - 对于
linked_to属性,直接传递原对象的引用,不做任何复制操作,这样就实现了保留原关联的需求。 - 把新创建的
Foo实例存入memo是必要操作,比如如果某个Foo的linked_to指向自身时,能避免陷入无限复制的死循环。
内容的提问来源于stack exchange,提问作者Anton Ovsyannikov
相关产品推荐
相关产品推荐

