为什么 Python 在打印时检测列表和字典中的自引用,而不是在类中

问题描述

这是一个关于 Python 语言设计的问题,出于好奇心。

Python 能够在打印循环和字典时检测自引用

l = [1,2,3,[98,99]]
l[3].append(l)
print(f"{l = }")
# l = [1,99,[...]]]

d = {1:None,2:None,3:None,4:{}}
d[4][98] = d
print(f"{d = }")
# d = {1: None,2: None,3: None,4: {98: {...}}}

但是当类对象有自引用时不这样做

class Node():
    def __init__(self,name,parent):
        self.children = []
        self.name,self.parent = name,parent
    def __repr__(self):
        return f"{self.name}: p={self.parent},"+\
    f"{[c for c in self.children]}"

top = Node("apex",None)
top.children += [Node("alpha",top),Node("beta",top)]
print(top)
# RecursionError: maximum recursion depth exceeded while getting the repr of an object

很容易检测到,下面是一个装饰器来做到这一点。我想知道为什么它没有自动完成是否有一些理论上的原因。

# Comments on my code are welcome,I want to improve
""" foo is a class-decorator.
It takes the parameter,a function,and returns another function
that accepts a class as a parameter,the second function returns an
amended copy of the class that has a new __repr__() function """
def foo(default=lambda x:"<...>"):
    def bar(origcls):
        # Note that default is available within this inner-program.
        # Amend __repr__ so that it saves the id of the object
        # and behaves differently if it has been seen before.
        # Use the class-static variable _reprlist to record calls
        # and the default-program to calculate the return if this
        # object is being re-visited 
        try:
            origcls._reprlist
        except:
            origcls._reprlist = set()
        oldrepr = origcls.__repr__
        def __repr__(self):
            if id(self) in origcls._reprlist:
                return default(self)
            else:
                origcls._reprlist.add(id(self))
                answer = f"{oldrepr(self)}"
                origcls._reprlist.remove(id(self))
                return answer
        origcls.__repr__ = __repr__
        return origcls
    return bar

@foo(lambda x:f"<<{x.name}>>")
class Node():
    def __init__(self,top)]
print(top)
# apex: p=None,[alpha: p=<<apex>>,[],beta: p=<<apex>>,[]]

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)