@songying
        
        2018-12-06T07:56:29.000000Z
        字数 2298
        阅读 1227
    python高级特性
https://woodpecker.org.cn/diveintopython3/special-method-names.html
new#object.new">https://docs.python.org/3/reference/datamodel.html?highlight=new#object.new
首先,很多情况下特殊方法的调用是隐式的,通常我们的代码无需直接使用特殊方法。除非有大量的元编程存在,直接调用特殊方法的频率应该远远低于你去实现它们的次数(__init__例外)。
一般来说,如果我们可以通过内置函数,操作符等来调用特殊方法,内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快。
| 算术运算符 | 正向方法 | 反向方法 | 
|---|---|---|
| + | __add__(self, other) | __radd__(self, other) | 
| - | __sub__(self, other) | __rsub__(self, other) | 
| * | __mul__(self, other) | __rmul__(self, other) | 
| / | __truediv__(self, other) | __rtruediv__(self, other) | 
| // | __floordiv__(self, other) | _rfloordiv__(self, other) | 
| % | __mod__(self, other) | __rmod__(self, other) | 
| ** | __pow__(self, other) | __rpow__(self, other) | 
| 内置函数: divmod(a, b) | __divmod__(self, other) | __rdivmod__(self, other) | 
| @ | __matmul__(self, other) | __rmatmul__(self, other) | 
| 位操作 | 正向方法 | 反向方法 | 
|---|---|---|
| & | __and__(self, other) | __rand__(self, other) | 
| | | __or__(self, other) | __ror__(self, other) | 
| ^ | __xor__(self, other) | __rxor__(self, other) | 
| ~ | __invert__(self) | |
| << | __lshift__(self, other) | __rlshift__(self, other) | 
| >> | __rshift__(self, other) | __rrshift__(self, other) | 
| 复合运算符 | 方法 | 
|---|---|
| += | __iadd__(self, other) | 
| -= | __isub__(self, other) | 
| *= | __imul__(self, other) | 
| /= | __itruediv__(self, other) | 
| //= | _ifloordiv__(self, other) | 
| %= | __imod__(self, other) | 
| **= | __ipow__(self, other) | 
| &= | __iand__(self, other) | 
| ` | =` | 
| ^= | __ixor__(self, other) | 
| <<= | __ilshift__(self, other) | 
| >>= | __irshift__(self, other) | 
| @ | __imatmul__(self, other) | 
| 比较运算符 | 方法 | 
|---|---|
| == | __eq__(self, other) | 
| != | __ne__(self, other) | 
| < | __lt__(self, other) | 
| <= | __le__(self, other) | 
| > | __gt__(self, other) | 
| >= | __ge__(self, other) | 
| 操作符 | 方法 | 
|---|---|
| in, not in | __contains__(self, item) | 
| 操作符 | 特殊方法 | 
|---|---|
| +x | __pos(self) | 
| -x | __neg__(self) | 
| abs(x) | __abs__(self) | 
| ~ | __invert__(self) | 
and, or, not 均没有可重载的特殊方法。
对于同时实现了正向方法与反向方法的运算符,其有一些特殊性,它们一般被称为中缀操作符。
注意:中缀运算符的基本原则就是不改变操作对象,而是产出一个新的值。
对于中缀运算符特殊方法,python提供了特殊分派机制,对于 a+b而言,解释器经过了以下过程:
- 如果a 有
__add__方法, 且返回值不是 NotImplemented,则调用a.__add__(b),然后返回结果。- 如果 a 没有
__add__方法, 或者调用__add__方法返回NotImplemented, 检查b 有没有__radd__方法,如果有,而且没有返回 NotImplemented,调用b.__radd__(a),然后返回结果。- 如果 b 没有
__radd__方法,或者调用__radd__方法返回 NotImplemented,抛出TypeError,并在错误消息中指明操作数类型不支持。
如果中缀运算符抛出异常,就终止了运算符分派机制。对 TypeError来说,通常最好将其捕获,然后返回NotImplemented。这样,解释器会尝试调用反向运算符方法,如果操作数是不同的类型,对调之后,反向运算符方法可能会正确计算。
