gpt4 book ai didi

python - 为什么不能动态地将 `__call__` 方法添加到实例中?

转载 作者:IT老高 更新时间:2023-10-28 21:11:28 26 4
gpt4 key购买 nike

在 Python 2 和 Python 3 中的代码:

class Foo(object):
pass

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

f(1, 2, 3)

返回错误Foo 对象不可调用。为什么会这样?

PS:对于旧式类,它可以按预期工作。

PPS:这种行为是有意的(参见接受的答案)。作为一种变通方法,可以在类级别定义一个 __call__,它只是转发给另一个成员,并将这个“普通”成员设置为每个实例的 __call__ 实现。

最佳答案

双下划线方法总是在类上查找,而不是在实例上。见 Special method lookup for new-style classes :

For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

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

例如,类是可调用的(这就是您生成实例的方式),但是如果 Python 在实际对象上查找 __call__ 方法,那么您永远做不到等等为其实例实现 __call__ 的类。 ClassObject() 将变为 ClassObject.__call__() 会失败,因为 self 参数未传递给未绑定(bind)的方法。所以改为使用 type(ClassObject).__call__(ClassObject) ,调用 instance() 转换为 type(instance).__call__(instance).

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

关于python - 为什么不能动态地将 `__call__` 方法添加到实例中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33824228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com