我需要更改给定对象的 __call__
方法的行为。天真的方法是这样的:
class A(object):
def __call__(self):
return 1
def new_call():
return 42
a = A()
a.__call__ = new_call
为什么不是a()
42的输出?有没有我可以利用的解决方法来达到相同的效果? (不使用类)
============================= 编辑================== ===============
根据记录,简短的回答是否定的。 Python 直接在类而不是实例上调用像 __call_
这样的“特殊方法”,因此如果您需要更改方法,则需要在类本身上进行更改。
最佳答案
特殊方法(又名“dunder”方法)是根据对象的类查找的,因此要覆盖它,您需要更改类,而不是实例。另请注意,方法都有一个初始参数传递给它们,通常称为 self
。
以下将做你想做的(注意它如何影响类的所有个实例):
class A(object):
def __call__(self):
return 1
def new_call(self):
return 42
a1 = A()
a2 = A()
A.__call__ = new_call
print(a1()) # -> 42
print(a2()) # -> 42
如果你只想改变一个特定的实例,一个相对简单的解决方法是让类的 __call_()
方法调用一个 不是 喜欢它的“特殊”方法是——即通过引入一个间接级别。
这就是我的意思:
# Workaround
class B(object):
def __call__(self):
return self.call_method(self)
@staticmethod
def call_method(self):
return 1
def new_call(self):
return 42
# Create two instances for testing.
b1 = B()
b2 = B()
b2.call_method = new_call # Will only affect this instance.
print(b1()) # -> 1
print(b2()) # -> 42
关于python - 是否可以覆盖类的 __call__ 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60062100/