2014-09-26 56 views
4

python在哪裏得到仍然產生'foo'的repr,即使在原始的方法被覆蓋之後?Python:爲什麼動態添加的__repr__方法不會覆蓋默認值

class Test(object): 
    def __init__(self, name, number_array): 
     self.name = name 
     self.number_array = number_array 
    def __repr__(self): 
     return str(self.name) 

def custom_repr(self): 
    return str(self.name*4) 

>>> A = Test('foo', [1,2]) 
>>> A 
foo 
>>> A.__repr__ = custom_repr.__get__(A, A.__class__) 
>>>A.__repr__() 
foofoofoofoo 
>>>A 
foo 
+0

不,你說得對,我認爲它是重複的,只有你問這個問題的方式稍微有點 - 所以我不能馬上告訴:) – user3467349 2014-09-26 01:27:37

+0

你說得對,它是一個dup,但我真的不喜歡那裏的答案。它沒有鏈接到文檔,它推測(不正確)的基本原理,它聽起來像Python保證所有的特殊方法總是在課堂上查找...所以我在那裏複製我的答案。 – abarnert 2014-09-26 01:31:04

+0

PS,當dup評論被自動刪除時,你是否失去了你的評論upvote rep? (不是很重要,但我有點兒好奇。) – abarnert 2014-09-26 01:40:57

回答

3

Special Method Lookup解釋說:

對於定製類,特殊的方法隱含調用只能保證正常工作,如果一個對象的類型定義,而不是在對象的實例字典...除了繞過任何實例在正確的利益屬性,隱含的特殊方法查找通常也繞過即使對象的元類

(我已經剪掉了那部分解釋了這樣做的理由,如果你有興趣,該__getattribute__()方法。 )

Python沒有準確記錄實現應該或不應該在類型上查找方法的時間;它的所有文檔實際上是實現可能會或可能不會查看特殊方法查找的實例,因此您不應該依賴這兩個實例。

但是,從您的測試結果中可以猜出,在CPython實現中,__repr__是查找該類型的函數之一。

0

__repr__直接擡頭的類,而不是實例,當它擡頭通過repr或類似的(例如,當它是由交互式解釋調用)。如果你必須猴子補丁repr,請在課堂上做(但請不要)。

這個相同的基本規則適用於大多數dunder方法。

+0

所以你的意思是在這種情況下動態添加__repr__方法是不可能的? – user3467349 2014-09-26 01:24:37

+0

@ user3467349,將其添加到實例不起作用。 (如果你必須爲一個特定的實例猴子補丁一個新的'__repr__'(請隨時*不要*這樣做),在課堂上這樣做,特別是用'is'來包裝實例。) – 2014-09-26 01:26:18

+0

不幸的是,猴子補丁班的每一個對象,這真的不是我想要的。 – user3467349 2014-09-26 01:30:53