首页 > 解决方案 > 如何打印可以包含自身的类

问题描述

我有一个功能类似于列表的类。它可以包含自己,这会导致打印问题。Python 通过用省略号替换递归部分来处理这个问题。当嵌套很简单时,我可以a = []; a.append(a)通过将单个项目与自我进行比较来做到这一点,但是当存在更复杂的关系时,这不起作用。用省略号或劫持蟒蛇打印机制替换递归部分的好方法是什么?我试图从 self 和 return 的值中构造一个列表str(mylist),但我也得到了一个递归错误。

class foo:
    def __init__(self):
        #stuff happens

    def __repr__(self):
        s = []
        for i in range(self.length):
            if self[i] is self:
                s.append("[...]")
            else:
                s.append(repr(self[i]))
        return f"[{','.join(s)}]"

class bar:
    def __init__(self):
        # stuff happens

    def __repr__(self):
        return str(list(self))

a = foo()
b = foo()
a.append(b)
b.append(a)
print(a)
RecursionError: maximum recursion depth exceeded

a = bar()
b = bar()
a.append(b)
b.append(a)
print(a)
RecursionError: maximum recursion depth exceeded

标签: pythonpython-3.xclassrecursion

解决方案


使用snakecharmerb 推荐的reprlib,我用装饰器解决了这个问题reprlib.recursive_repr。该函数的描述是:

@reprlib.recursive_repr(fillvalue="...")

__repr__()用于检测同一线程内递归调用的方法的装饰器。如果进行递归调用,则返回填充值,否则进行通常的__repr__() 调用。

我使用"[...]"带括号的填充值,否则结果可能最终看起来[3, ...]不漂亮,而不是 python 格式化列表的方式。

@reprlib.recursive_repr("[...]")
def __repr__(self):
    return f"[{','.join(map(repr, self))}]"

推荐阅读