Python:带有`__call__`的对象不可调用

时间:2019-02-28 17:30:56

标签: python

我给人的印象是python中任何具有__call__属性的对象都是可调用的,但事实并非如此。特别是,似乎不支持在__call__中设置__init__-参见下文。可调用对象到底需要什么?为什么这种方式行不通?

class A:
    def __init__(self):
        self.__call__ = self.double

    def double(self, x):
        """Doubles `x`."""
        return 2 * x

a = A()
try:
    print(a(3))
except TypeError as e:
    print(e) # 'A' object is not callable
print(a.__call__(3)) # 6
print(a.__call__.__doc__) # 'Doubles `x`.'

以上是我真正的问题,但这是我的动力,如果您有兴趣/认为有更好的方法可以实现我的目标。我希望__call__是另一个实例方法的包装,尤其是具有相同的文档字符串。我可以这样实现:

from functools import wraps

class B:
    def double(self, x):
        """Doubles `x`."""
        return 2 * x

    @wraps(B.double)
    def __call__(self, x):
        return self.double(x)

b = B()
print(b(3)) # 6
print(b.__call__.__doc__) # 'Doubles `x`.'

但是问题是,如果我有另一个继承自B的类并更改了double的文档字符串,那么将使用B.double.__doc__

class B2(B):
    def double(self, x):
        """Returns twice `x`."""
        return 2 * x

b2 = B2()
print(b2(3)) # 6
print(b2.__call__.__doc__) # 'Doubles `x`.'

这就是为什么我希望在__call__中将double设置为__init__的原因。

0 个答案:

没有答案