@songying
2018-12-06T15:56:29.000000Z
字数 2298
阅读 1005
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。这样,解释器会尝试调用反向运算符方法,如果操作数是不同的类型,对调之后,反向运算符方法可能会正确计算。