为什么不动态地将`__call__`方法添加到实例工作中?

650*_*502 17 python instance

在Python 2和Python 3中代码:

class Foo(object):
    pass

f = Foo()
f.__call__ = lambda *args : args

f(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

返回错误Foo object is not callable.为什么会这样?

PS:对于旧式的类,它按预期工作.

PPS:此行为是有意的(请参阅接受的答案).作为一种解决方法,可以定义一个__call__类级别,它只是转发给另一个成员,并将这个"普通"成员设置为每个实例的__call__实现.

Mar*_*ers 21

总是在类上查找双下划线方法,而不是实例.请参阅新样式类的特殊方法查找:

对于新式类,只有在对象的类型上定义,而不是在对象的实例字典中,才能保证对特殊方法的隐式调用才能正常工作.

那是因为类型可能需要支持相同的操作(在这种情况下,特殊方法会在元类型上查找).

例如,类是可调用的(这就是你生成实例的方式),但是如果Python 在实际对象上查找__call__方法,那么你就永远不能在为它们的实例实现的类上这样做.将成为哪个会失败,因为参数未传递给未绑定的方法.所以改为使用,并且调用转换为.__call__ClassObject()ClassObject.__call__()selftype(ClassObject).__call__(ClassObject)instance()type(instance).__call__(instance)

要解决此问题,您可以__call__向类中添加一个方法,该方法检查类的__call__属性,如果存在,则调用它.