[关闭]
@songying 2018-12-06T15:56:29.000000Z 字数 2298 阅读 1005

python中的特殊方法

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

https://pycoders-weekly-chinese.readthedocs.io/en/latest/issue6/a-guide-to-pythons-magic-methods.html

如何使用特殊方法?

首先,很多情况下特殊方法的调用是隐式的,通常我们的代码无需直接使用特殊方法。除非有大量的元编程存在,直接调用特殊方法的频率应该远远低于你去实现它们的次数(__init__例外)。

一般来说,如果我们可以通过内置函数,操作符等来调用特殊方法,内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快。

运算符重载

1. 算术运算符

算术运算符 正向方法 反向方法
+ __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)

2. 位操作符

位操作 正向方法 反向方法
& __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)

3. 复合运算符

复合运算符 方法
+= __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)

4. 比较运算符

比较运算符 方法
== __eq__(self, other)
!= __ne__(self, other)
< __lt__(self, other)
<= __le__(self, other)
> __gt__(self, other)
>= __ge__(self, other)

5. in, not in

操作符 方法
in, not in __contains__(self, item)

6. 一元运算符

操作符 特殊方法
+x __pos(self)
-x __neg__(self)
abs(x) __abs__(self)
~ __invert__(self)

7. 逻辑运算符

and, or, not 均没有可重载的特殊方法。

正向方法与反向方法

对于同时实现了正向方法与反向方法的运算符,其有一些特殊性,它们一般被称为中缀操作符。

注意:中缀运算符的基本原则就是不改变操作对象,而是产出一个新的值。

对于中缀运算符特殊方法,python提供了特殊分派机制,对于 a+b而言,解释器经过了以下过程:

  1. 如果a 有__add__ 方法, 且返回值不是 NotImplemented,则调用 a.__add__(b),然后返回结果。
  2. 如果 a 没有 __add__方法, 或者调用 __add__ 方法返回 NotImplemented, 检查b 有没有 __radd__ 方法,如果有,而且没有返回 NotImplemented,调用b.__radd__(a),然后返回结果。
  3. 如果 b 没有 __radd__方法,或者调用 __radd__ 方法返回 NotImplemented,抛出TypeError,并在错误消息中指明操作数类型不支持。

如果中缀运算符抛出异常,就终止了运算符分派机制。对 TypeError来说,通常最好将其捕获,然后返回NotImplemented。这样,解释器会尝试调用反向运算符方法,如果操作数是不同的类型,对调之后,反向运算符方法可能会正确计算。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注