以此为例:
class Foo(object):
def __init__(self, msg):
self._msg = msg
def __call__(self):
return self._msg
foo = Foo('hello')
print(foo()) # Prints 'hello'
foo.__call__ = lambda _: 'bye'
print(foo()) # Prints 'hello'
我可以在 Python 2.x 和 Python 3.x
上重现这一点我无法找到有关此行为的文档的任何相关信息。
这对我来说看起来像是一个有效的用例,特别是在monkeypatching stuff。
是否有理由不允许这样做?
答案 0 :(得分:2)
当您使用()
调用对象时,它会执行在对象类型上定义的__call__
方法。因此,__call__
在类Foo
上定义,而不是在您的实例foo
上定义。如果您重新分配Foo.__call__
,它就可以运行。
Foo.__call__ = lambda _: 'bye'
print(foo()) # prints 'bye'
答案 1 :(得分:1)
试试这个:
class Foo(object):
def __init__(self, msg):
self._msg = msg
def __call__(self):
return self._msg
foo = Foo('hello')
print(foo()) # Prints 'hello'
Foo.__call__ = lambda _: 'bye' #Notice the capital F, this is the class not the instance
print(foo()) # Prints 'bye'
最后一次通话应按照您的预期打印'再见'。当你调用一个实例的函数时,它实际上是指类函数(它们被定义的地方)
答案 2 :(得分:1)
通常,您可以这样做。覆盖单个实例的给定方法的实现,而不影响其余的。
这里的问题是你试图覆盖“特殊”方法。 ns
调用语法在类上查找()
方法,而不是实例。
以下代码显示您可以覆盖单个实例的方法实现,并且可以解决您的问题:
__call__
注意:以下内容也可以按预期工作:
class Foo(object):
def __init__(self, msg):
self._msg = msg
def __call__(self):
return self.call() # Delegate call to instance
def call(self):
return self._msg
foo = Foo('hello')
other = Foo('hi')
print(foo()) # Prints 'hello'
def new_call(self):
return "bye"
foo.call = new_call.__get__(foo, Foo)
print(foo()) # Prints 'bye'
print(other()) # Prints 'hi' (unaffected by override)
但我更喜欢明确的定义。