2014-09-26 31 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