python - 覆盖实例上的特殊方法

标签 python metaprogramming

希望对Python有深入了解的人可以回答这个问题:)

考虑以下代码:

>>> class A(object):
...     pass
...
>>> def __repr__(self):
...     return "A"
...
>>> from types import MethodType
>>> a = A()
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>> setattr(a, "__repr__", MethodType(__repr__, a, a.__class__))
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>>

请注意 repr(a) 不会产生 "A"的预期结果? 我想知道为什么会这样,是否有办法实现这一点......

相比之下,下面的例子可以工作(也许是因为我们没有试图覆盖一个特殊的方法?):

>>> class A(object):
...     def foo(self):
...             return "foo"
...
>>> def bar(self):
...     return "bar"
...
>>> from types import MethodType
>>> a = A()
>>> a.foo()
'foo'
>>> setattr(a, "foo", MethodType(bar, a, a.__class__))
>>> a.foo()
'bar'
>>>

最佳答案

Python 通常不会在实例上调用特殊方法(名称由 __ 包围的方法),而只会在类上调用。 (虽然这是一个实现细节,但它是标准解释器 CPython 的特性。)所以没有办法直接在实例上覆盖 __repr__() 并使其工作。相反,您需要这样做:

class A(object):
    def __repr__(self):
        return self._repr()
    def _repr(self):
        return object.__repr__(self)

现在您可以通过替换 _repr() 来覆盖实例上的 __repr__()

关于python - 覆盖实例上的特殊方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10376604/

相关文章:

ruby - 有没有办法在每个方法定义之后添加要运行的代码

Ruby 打印当前可见性

python - 如何解决错误 405 方法不允许,对于 django graphql 服务器和前端 react axios

Python 3 使用 continue 而不是 not (!=) 的用例

ruby - 请解释一下 ruby​​ 的这种元编程魔法

C++ 元编程创建一个新的类型列表,并将remove_const应用于每个元素

c++ - 元组和总结

python - 属性错误: 'FigureManagerBase' object has no attribut 'window'

python - 大型 Numpy Scipy CSR 矩阵,按行操作

python - 如何在 Python 中从 z、p、k 中找到增益 g