a+b等价于
import operator;operator.add(a,b)。首先调用
a.__add__(b),然后根据需要调用
b.__radd__(a)。但是
ifsubclass(type(b),type(a)),则先
b.__radd__(a)被称为。
根据有关“特殊”方法的文档:
- 关于
__add__()
:
__add__()被调用以实现二进制算术“ +”运算。例如,要评估表达式x +
y,其中x是具有__add__()方法的类的实例x.__add__(y)。如果这些方法之一不支持使用提供的参数进行的操作,则应返回 NotImplemented 。
- 关于
__radd__()
:
仅当左操作数不支持相应的操作并且操作数是不同类型时,才调用这些函数。例如,如果返回NotImplemented
__radd__(),y.__radd__(x)则调用求值x + y的表达式,其中y是具有方法的类的实例x.__add__(y)。如果右操作数的类型是左操作数类型的子类,并且该子类为操作提供了反映的方法,则将在左操作数的非反射方法之前调用此方法。此行为允许子类覆盖其祖先的操作。
根据行为举例说明:
情况1:
>>> print 1+c('C.__radd__', <__main__.C instance at 0x7ff5631397a0>, 1)reversed resultradd仅当左操作数不支持相应的操作并且操作数是不同类型时,才调用这些函数。在这种情况下,
1不支持类的添加,因此,它会退回到类的
__radd__()功能
C。如果
__radd__没有在
C()课堂上实施,它将退回到
__add__()
情况2:
>>> 1 .__add__(c)NotImplemented>>> c .__add__(1)('C.__add__', <__main__.C instance at 0x7ff563139830>, 1)'result'1 .__add__(c)给出
NotImplemented为
1是的
int类型和
add的
int类不支持
add使用C类对象。但是
c.__add(1)运行是因为
C()类支持。
情况3:
>>> int.__add__(1, c)NotImplemented>>> C.__add__(c, 1)('C.__add__', <__main__.C instance at 0x7ff5610add40>, 1)'result'类似于
case 2。但是在这里,调用是通过带有第一个参数的类作为该类的对象进行的。行为将是相同的。
情况4:
>>> int.__add__(c, 1)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: descriptor '__add__' requires a 'int' object but received a 'instance'>>> C.__add__(1, c)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unbound method __add__() must be called with C instance as first argument (got int instance instead)
反之亦然
case 3。从堆栈跟踪中可以清楚地看出,
__add__将调用类的对象作为第一个参数,否则将导致异常。



