数字魔法方法
就像你可以使用比较操作符来比较类的实例,你也可以定义数值操作符的行为。固定好你的安全带,这样的操作符真的有很多。
看在吉多·范罗苏姆的份上,我把它们分成了五类:一元操作符,常见算数操作符,反射算数操作符(后面会涉及更多),增强赋值操作符,和类型转换操作符。
一元操作符和函数
1. __pos__(self)
实现取正操作,例如 +some_object
。
2. __neg__(self)
实现取负操作,例如 -some_object
。
3. __abs__(self)
实现内建绝对值函数 abs()
操作。
4. __invert__(self)
实现取反操作符(~
)
5. __round__(self, n)
实现内建函数 round()
,n
是近似小数点的位数。
6. __floor__(self)
实现 math.floor()
函数的行为,即向下取整。
7. __ceil__(self)
实现 math.ceil()
函数的行为,即向上取整。
8. __trunc__(self)
实现 math.trunc()
函数,即距离零最近的整数。
常见数学操作符
现在,我们来看看常见的二元操作符(和一些函数),像+,-,*
之类的,它们很容易从字面意思理解。
1. __add__(self, other)
实现加法(+
)操作 (self + other
)
2. __sub__(self, other)
实现减法(-
)操作 (self - other
)
3. __mul__(self, other)
实现乘法(*
)操作 (self * other
)
4. __floordiv__(self, other)
实现使用 //
操作符的整数除法, 经典除法. (self // other
)
5. __truediv__(self, other)
实现使用/
操作符的除法, 真除法. (self / other
)
6. __mod__(self, other)
实现取模操作(%
) (self % other
)
7. __divmod__(self, other)
实现内置函数divmod
的作用.
8. __pow__(self, pow)
实现操作符(**
)的作用. (self ** pow
)
9. __lshift__(self, other)
实现左移运算符<<
(self << other
)
10. __rshift__(self, other)
实现右移运算符>>
(self >> other
)
11. __and__(self, other)
实现按位与(&
)运算符 (self & other
)
12 . __or__(self, other)
实现按位或(|
) 运算符 (self | other
)
13. __xor__(self, other)
实现按位异或(^
) 运算符 (self ^ other
)
反射算术运算符(Reflected arithmetic operators)
反射算术运算符听起来高大上, 其实他相当简单.
some_object + other
这是正常的加法,反射是一样的意思,只不过是运算符交换了一下位置:
other + some_object
所以, 所有反射运算符魔法方法和它们的正常版本做的工作相同,只不过是处理交换两个操作数之后的情况。(把 other
作为第一个参数, self
作为第二个参数)
绝大多数情况下,反射运算和正常顺序产生的结果是相同的,所以很可能你定义 __radd__
时只是调用一下 __add__
。注意一点,操作符左侧的对象(也就是上面的 other )一定不要定义操作符的非反射版本。例如,在上面的例子中,只有当 other 没有定义 __add__
时 some_object.__radd__
才会被调用。
__radd__(self, other)
Implements reflected addition.__rsub__(self, other)
Implements reflected subtraction.__rmul__(self, other)
Implements reflected multiplication.__rfloordiv__(self, other)
Implements reflected integer division using the // operator.__rtruediv__(self, other)
Implements reflected true division.
__rmod__(self, other)
Implements reflected modulo using the % operator.
__rdivmod__(self, other)
Implements behavior for long division using the divmod() built in function, whendivmod(other, self)
is called.__rpow__
Implements behavior for reflected exponents using the**
operator.__rlshift__(self, other)
Implements reflected left bitwise shift using the<<
operator.__rrshift__(self, other)
Implements reflected right bitwise shift using the>>
operator.__rand__(self, other)
Implements reflected bitwise and using the&
operator.__ror__(self, other)
Implements reflected bitwise or using the|
operator.__rxor__(self, other)
Implements reflected bitwise xor using the^
operator.
增强赋值运算符 (Augmented assignment)
Python同样提供了大量的魔法方法,可以用来自定义增强赋值操作的行为。或许你已经了解增强赋值,它融合了“常见”的操作符和赋值操作.
x = 5
x += 1
这些方法都应该返回左侧操作数应该被赋予的值(例如, a += b
, __iadd__
也许会返回 a + b
,这个结果会被赋给 a
),下面是方法列表:
__iadd__(self, other)
Implements addition with assignment.
__isub__(self, other)
Implements subtraction with assignment.
__imul__(self, other)
Implements multiplication with assignment.
__ifloordiv__(self, other)
Implements integer division with assignment using the //=
operator .
__itruediv__(self, other)
Implements true division with assignment.
__imod__(self, other)
Implements modulo with assignment using the %=
operator.
__ipow__
Implements behavior for exponents with assignment using the **=
operator.
__ilshift__(self, other)
Implements left bitwise shift with assignment using the <<=
operator.
__irshift__(self, other)
Implements right bitwise shift with assignment using the >>=
operator.
__iand__(self, other)
Implements bitwise and with assignment using the &=
operator.
__ior__(self, other)
Implements bitwise or with assignment using the |=
operator.
__ixor__(self, other)
Implements bitwise xor with assignment using the ^=
operator.
类型转换魔法方法
Python也有一系列的魔法方法用于实现类似 float()
的内建类型转换函数的操作。它们是这些:
__int__(self)
实现到int的类型转换。__float__(self)
实现到float的类型转换。__complex__(self)
实现到complex的类型转换。__oct__(self)
实现到八进制数的类型转换。__hex__(self)
实现到十六进制数的类型转换。__index__(self)
实现当对象用于切片表达式时到一个整数的类型转换。如果你定义了一个可能会用于切片操作的数值类型,你应该定义__index__
。__trunc__(self)
当调用math.trunc(self)
时调用该方法,__trunc__
应该返回 self 截取到一个整数类型的值。