__Add__ (und andere magische Methoden) dynamisch definieren [duplizieren]

Nov 24 2020

Ich habe gehört, dass a + bsich das ausdehnt a.__add__(b). In meinem Code funktioniert das jedoch nicht so. Nehmen Sie diesen Code:

class TestAdd:
    def __init__(self, a):
        self.a = a
    def __getattr__(self, name):
        if name == '__add__':
            return (lambda y: self.a + y)

Wenn ich es versuche TestAdd(5).__add__(1), gibt es 6 korrekt zurück. Wenn ich es versuche TestAdd(5) + 1, wird der folgende Fehler ausgelöst:

TypeError                                 Traceback (most recent call last)
<ipython-input-3-1c04c7082b89> in <module>
----> 1 TestAdd(5) + 1

TypeError: unsupported operand type(s) for +: 'TestAdd' and 'int'

Warum ist das? Vermisse ich etwas

Antworten

chepner Nov 24 2020 at 03:11

Magische Methoden werden nicht in Instanzen, sondern in Klassen nachgeschlagen. TestAdd(5) + 1ist genauer äquivalent zu tmp = TestAdd(5); TestAdd.__add__(tmp, 1)und Sie haben nicht definiert TestAdd.__add__.

AKX Nov 24 2020 at 03:10

Sie können __getattr__eine magische Methode nicht dynamisch zurückgeben. Dies wird ausführlich in 3.3.10 Spezielle Methodensuche im Handbuch dokumentiert.