Définition dynamique de __add__ (et d’autres méthodes magiques) [dupliquer]

Nov 24 2020

J'ai entendu que cela a + bs'étend à a.__add__(b). Cependant, cela ne fonctionne pas comme ça dans mon code. Prenez ce code:

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

Quand j'essaye TestAdd(5).__add__(1), il renvoie 6 correctement. Quand j'essaye TestAdd(5) + 1, cela soulève cette erreur:

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'

Pourquoi est-ce? Est-ce que je manque quelque chose?

Réponses

chepner Nov 24 2020 at 03:11

Les méthodes magiques ne sont pas recherchées sur les instances, mais sur les classes. TestAdd(5) + 1équivaut plus précisément à tmp = TestAdd(5); TestAdd.__add__(tmp, 1), et vous n'avez pas défini TestAdd.__add__.

AKX Nov 24 2020 at 03:10

Vous ne pouvez pas utiliser __getattr__pour renvoyer dynamiquement une méthode magique; ceci est documenté en détail dans 3.3.10 Recherche de méthode spéciale dans le manuel.