python - 是否可以覆盖类的 __call__ 方法?

标签 python python-3.x

我需要更改给定对象的 __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/

相关文章:

python - 即使学习率很小,当类别数量增加时,“模型因损失= NaN而发散”。 [ tensorflow ]

python - 为什么 Python 返回 [15] for [0xfor x in (1, 2, 3)]?

python - 将函数应用于 Pandas 数据框的列

python - 带有嵌套过滤器的Elasticsearch-dsl以及完全匹配的AND和OR条件

python - 使用 __import__ 从同名模块导入对象

python - 从包含键和字典项嵌套列表的字典创建 Pandas DataFrame

python - 在元组列表中找到一个精确的元组匹配并返回它的索引

python - 如何设置 GtkImage 的大小

python - Jupyter nbconvert LaTex 导出主题

python - 如何强制 Pandas dataframe 列查询仅返回 str 而不解释它所看到的内容?