简体   繁体   English

用 __getattr__ 覆盖魔法方法

[英]overriding magic methods with __getattr__

I have a class, that is a container for members.我有一个类,它是成员的容器。 all members are of the same type.所有成员都属于同一类型。

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)

the __getattr__ overrides the do method: __getattr__覆盖了do方法:

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

and even overrides __add__ when called explicitly甚至在显式__add__时覆盖__add__

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

but __add__ fails when called as +但是__add__在调用为+时失败

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

How can I override magic methods to work as expected?如何覆盖魔术方法以按预期工作?

The reason why operators aren't handled by __getattr__ is covered in Why is __getattr__ capable of handling built-in operator overloads in python 2.x?为什么__getattr__不处理运算符的原因在为什么 __getattr__ 能够处理 python 2.x 中的内置运算符重载?

In new-style classes the special methods are always looked up in the class(implicit lookup) not instance.在新式类中,特殊方法总是在类中查找(隐式查找)而不是实例。

My workaround (not perfect, but allows to make it work) would be to explicitly define the required dunder methods in B , and explicitly call __getattr__ on them:我的解决方法(不完美,但允许使其工作)是在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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM