Python:使用__repr__时出现无法解释的无限递归

3

这里有一段代码,进入了一个无限递归循环,只包含一个 __repr__ 函数,似乎在不停地调用自己。但我实在看不出来它是如何调用自己的。更奇怪的是,我甚至无法理解它是如何被调用的:

class MyList(list): #this is storage for MyDict objects
    def __init__(self):
        super(MyList, self).__init__()

class MyDict(dict):
    def __init__(self, mylist):
        self.mylist = mylist #mydict remembers mylist, to which it belongs
    def __hash__(self):
        return id(self)
    def __eq__(self, other):
        return self is other
    def __repr__(self):
        return str(self.mylist.index(self)) #!!!this is the crazy repr, going into recursion
    def __str__(self):
        return str(self.__repr__())

mylist = MyList()
mydict = MyDict(mylist)
mydict.update({1:2})
print str(mylist.index(mydict)) #here we die :(

执行此代码的结果为:
Traceback (most recent call last):
  File "test_analogue.py", line 20, in <module>
    print str(mylist.index(mydict))
  File "test_analogue.py", line 13, in __repr__
    return str(self.mylist.index(self))
  File "test_analogue.py", line 13, in __repr__
  ... 
  ... (repetition of last 2 lines for ~666 times)
  ...
  File "test_analogue.py", line 13, in __repr__
    return str(self.mylist.index(self))
  RuntimeError: maximum recursion depth exceeded while calling a Python object

您能理解如何调用__repr__str(mylist.index(mydict))吗?我完全被困惑了。谢谢!


定义的 __repr__ 函数覆盖了默认的 str(mylist.index(mydict)) 调用的 __repr__。注释掉你的 __repr__ 函数,然后看看!!! - DOOM
@DOOM 不好意思,但我看不出来 str(mylist.index(mydict)) 如何调用 __repr__mylist.index(mydict) 应该返回一个 int,而 int 应该通过 str(<int>) 转换为 str。这里的 __repr__ 在哪里? - Boris Burkov
2
问题出在抛出的异常上,因为 mydict 不在 mylist 中。该异常试图获取字典的 repr。 - kwatford
@kwatford 兄弟,你说得对。如果我在这些事情上瞪大眼睛,那我最好还是休假一下。谢谢你们。 - Boris Burkov
1个回答

5
>> mylist.index('foo')
ValueError: 'foo' is not in list

您实际上从未将mydict添加到mylist中,因此index方法试图引发此错误。该错误包含字典的repr。当然,字典的repr尝试在它不在的列表中查找其index,这会引发异常,其错误消息是使用字典的repr计算的,当然,字典的repr尝试在它不在的列表中查找其index,而...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接