2014-03-25 61 views
3

這是一段代碼,它進入了一個無限遞歸循環,它只包含__repr__函數,看起來自己調用它。但我真的看不到,它是如何稱呼它自己的。此外,我竟然不能懂,它是如何調用:在這段代碼的結果python:無法解釋的無限遞歸__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 

你明白,怎麼str(mylist.index(mydict))設法打電話__repr__?我完全困惑。謝謝!

+0

'__repr__'函數定義覆蓋默認'__repr__',它由'str(mylist.index(mydict))'調用。註釋掉你的'__repr__'函數,然後看!!! – DOOM

+0

@DOOM對不起,但我看不到,'str(mylist.index(mydict))'調用'__repr__'的方式。 'mylist.index(mydict)'應該返回一個'int','int'應該由'str()'轉換爲'str'。 '__repr__'在哪裏? –

+2

問題在於拋出的異常,因爲'mydict'不在'mylist'中。例外試圖獲得字典的repr。 – kwatford

回答

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

您從未真正將mydict添加到mylist,因此index方法會嘗試引發此錯誤。該錯誤包含字典的repr。字典的repr當然會嘗試在列表中查找它的index,這會引發一個異常,它的錯誤信息是使用字典的repr來計算的,當然這是嘗試查看的將它的index放在它不在的列表中,並且......