python - 使用 __getattr__ 覆盖魔术方法

标签 python python-3.x magic-methods

我有一个类,它是成员的容器。所有成员都属于同一类型。

class A(int):
    def __init__(self, n):
        super().__init__()
        self.n = n

    def do(self):
        print('adding 10')
        return self.n + 10


class B:
    def __init__(self, a1, a2):
        self.a = [a1, a2]

    def __getattr__(self, item):
        return getattr(self.a[0], item)


a1 = A(10)
a2 = A(5)
b = B(a1, a2)

__getattr__ 覆盖 do 方法:

In[7]: b.do()
adding 10
Out[7]: 20

甚至在显式调用时覆盖__add__

In[8]: b.__add__(1)
Out[8]: 11

但是 __add__ 当作为 + 调用时失败

In[9]: b+1
TypeError: unsupported operand type(s) for +: 'B' and 'int'

如何重写魔术方法以按预期工作?

最佳答案

Why is __getattr__ capable of handling built-in operator overloads in python 2.x? 中介绍了 __getattr__ 不处理运算符的原因。

In new-style classes the special methods are always looked up in the class(implicit lookup) not instance.

我的解决方法(并不完美,但允许使其工作)是在 B 中显式定义所需的 dunder 方法,并在它们上显式调用 __getattr__ :

class B:
    def __init__(self, a1, a2):
        self.a = [a1, a2]

    def __add__(self,other):
        return self.__getattr__("__add__")(other)

    def __getattr__(self, item):
        return getattr(self.a[0], item)

关于python - 使用 __getattr__ 覆盖魔术方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59683994/

相关文章:

python - pygame图像碰撞问题

python - python解析XML并删除容器

php - 在PHP魔术方法上处理 “not found”案例的最佳方法是什么?

python - 我应该直接使用python魔术方法吗?

python - 发布后单用户补丁时jmeter引发线程异常

python - 复杂的 Pandas 聚合后如何收集列值

python - 将 win32com 与多线程一起使用

php - 用户定义的魔法方法 : What is "documented magic functionality"?

python - key 错误 : 'SPARK_HOME' in pyspark

python - 用spawnProcess扭曲管道两个进程