微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决为什么 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 举报,一经查实,本站将立刻删除。