-1

我之前问过为什么并返回 NotImplemented 的相同问题,但由于可能重复,该问题已关闭。10 .__add__(5.5)10. __radd__ (5.5)

“重复”之一的答案表明:

a + b不直接翻译成a.__add__(b). b.__radd__(a)如果a.__add__不存在或返回,它也会尝试NotImplemented

该答案表明要么__add____radd__应该工作,但既不工作__add__也不__radd__真正工作,如我上面的代码所示。

另一个“重复”的答案是:

a+b 等价于导入操作符;运算符.add(a,b)。它首先调用a.__add__(b),然后,如有必要,b.__radd__(a)

同样,既不__add__也不__radd__做这项工作。因此,这些答案基本上是在解释Python 文档关于特殊方法的内容,这些方法指出,当首先调用+运算符时__add__,然后__radd__if__add__不成功。__radd__不成功时会发生什么?

4

1 回答 1

1

我想你没有意识到运算符被交换为反向操作。它是b.__radd__(a)——它调用__radd__了另一个操作员!

所以因为10 .__add__(5.5)返回NotImplemented它调用5.5 .__radd__(10)(返回15.5) not 10. __radd__ (5.5)。如果__radd__交换运算符上的 也返回NotImplemented,Python 将引发适当的TypeError.

这个片段演示了如何调用这些方法+(以及如果两者都返回会发生什么NotImplemented):

class T:
    def __init__(self, value):
        self._value = value

    def __repr__(self):
        return f"{type(self).__name__}({self._value})"

    def __add__(self, other):
        print(f'called {self!r}.__add__({other!r})')
        return NotImplemented

    def __radd__(self, other):
        print(f'called {self!r}.__radd__({other!r})')
        return NotImplemented

class U(T):
    ...

>>> T(1) + U(2)
called T(1).__add__(U(2))
called U(2).__radd__(T(1))

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
---> 19 T(1) + U(2)
TypeError: unsupported operand type(s) for +: 'T' and 'U'

因为__radd__仅在操作数的类不同时才调用,因此我需要在此示例中创建第二个类。

但是,您真的不应该直接调用特殊方法,如果您需要一个函数来执行这样的操作,您可以operator.add在您的情况下使用。

于 2020-01-08T12:09:01.927 回答