【问题标题】:Deepcopy on two classes containing eachother gives recursion error. Python对包含彼此的两个类进行深度复制会产生递归错误。 Python
【发布时间】:2020-06-07 21:48:31
【问题描述】:

当我有这样的对象结构时:

from copy import deepcopy

class A:
    def __init__(self, b):
        self.b = b
    def __deepcopy__(self, memodict):
        return A(deepcopy(self.b, memodict))

class B:
    def __init__(self, a):
        self.a = a
    def __deepcopy__(self, memodict):
        return B(deepcopy(self.a, memodict))

test_a = A(None)
test_b = B(None)
test_a.b = test_b
test_b.a = test_a
copy_a = deepcopy(test_a)

我尝试对对象进行深度复制,但出现“超出最大递归深度”错误。 我明白为什么会发生这种情况,但我不知道解决这个问题的最佳方法是什么?

帮助非常感谢

【问题讨论】:

  • 要了解递归,首先要了解递归。不过说真的:您的代码正在调用自身,以至于调用堆栈超出了允许的大小 (sys.maxrecursionlimit)。您需要一个基本情况或突破条件来防止这种情况发生。
  • 您应该发布一些示例测试以查看递归问题在哪里。对象是如何被引用来吃其他东西的?
  • 您应该在问题中发布经过测试和工作的示例。
  • @JacobIRR 是的,我明白,只是因为网上的例子是这样的,所以我认为 copy.deepcopy 函数可以处理基本情况。
  • @nadapez 对不起,编辑了它,所以它有一个工作示例

标签: python python-3.x recursion deep-copy


【解决方案1】:

你不应该重写__deepcopy__,让 deepcopy 函数完成它的工作。 顺便说一句,我不得不删除注释 :B,因为它是一个前向引用并给出了名称错误。

from copy import deepcopy

class A:
    def __init__(self, b):
        self.b = b

class B:
    def __init__(self, a):
        self.a = a


a = A(None)
b = B(None)
a.b = b
b.a = a

aa = deepcopy(a)

print (aa is a) # -> False
print(aa.b is b) # -> False
print(aa.b.a is aa) # -> True

但是,如果您出于任何原因想要覆盖 __deepcopy__,您应该这样做:

from copy import deepcopy


class A:
    def __init__(self, b):
        self.b = b

    def __deepcopy__(self, memodict):
        a = A(None)
        memodict[id(self)] = a
        a.b = deepcopy(self.b, memodict)
        return a


class B:
    def __init__(self, a: A):
        self.a = a

    def __deepcopy__(self, memodict):
        b = B(None)
        memodict[id(self)] = b
        b.a = deepcopy(self.a, memodict)
        return b


a = A(None)
b = B(None)
a.b = b
b.a = a

aa = deepcopy(a)
print(aa is a)  # -> False
print(aa.b is b)  # -> False
print(aa.b.a is aa)  # -> True

参考:https://stackoverflow.com/a/15774013/1951448

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 2021-12-11
    • 2015-12-26
    相关资源
    最近更新 更多