python_魔法方法(二):算术运算
python2.2之后,对类和类型做了同意,将int()、float()、str()、list()、touple()这些BIF转换为工厂函数
>>> type(len) <class 'builtin_function_or_method'> >>> type(int) <class 'type'> >>> type(dir) <class 'builtin_function_or_method'> >>> type(list) <class 'type'>
在来看一个例子
>>> class C(): pass >>> type(C) <class 'type'>
它的类型是type类型,也是类对象,其实所谓的工厂函数,就是一个类对象,当你调用他们的时候,实际上就是创建一个实例对象:
>>> type(C) <class 'type'> >>> a = int('123') >>> b = int('456') >>> a + b 579
由此可以看出,对象是可以计算的。python中无处不对象,当在求a+b等于多少的时候,事实上python就是将两个对象进行相加操作。python的魔法方法还体统了自定义对象的数值处理,通过对下面这些魔法方法的重写,可以自定义任何对象间的算术运算。
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) __divmod__(self,other):定义当被divmod()调用时行为 __rdivmod__(self,other) __pow__(self,other):乘方** __rpow__(self,other) __rshift__(self,other)和__lshift__(self,other):左移位<<和右移位>> __rrshift__(self,other)和__rlshift__(self,other) __and__(self,other):按位与& __rand__(self,other) __xor__(self,other):按位或^ __rxor__(self,other) __or__(self,other):按位或操作的行为 __ror__(self,other)
举个例子
>>> class New_int(int): def __add__(self,other): return int.__sub__(self,other) def __sub__(self,other): return int.__add__(self,other) >>> a = New_int(3) >>> b = New_int(5) >>> a 3 >>> b 5 >>> a + b -2 >>> a - b 8
这里用了python默认的方法,如果自己定义了,尝试一下就会发现错误
>>> class Try_int(int): def __add__(self,other): return self + other #出现了无限递归,主要原因在于:对象涉及加法操作,自动调用了魔法方法__add__(),返回return self+other也就是对象本身加另一个对象,形成了无限递归 def __sub__(self,other): return self - other >>> a = Try_int(1) >>> b = Try_int(2) >>> a + b Traceback (most recent call last): File "<pyshell#44>", line 1, in <module> a + b File "<pyshell#41>", line 3, in __add__ return self + other File "<pyshell#41>", line 3, in __add__ return self + other File "<pyshell#41>", line 3, in __add__ return self + other [Previous line repeated 327 more times] RecursionError: maximum recursion depth exceeded while calling a Python object
上面例子可以修改下,就不会出现无限递归了
>>> class Try_int(int): def __add__(self,other): return int(self) + int(other) def __sub__(self,other): return int(self) - int(other) >>> a = Try_int(1) >>> b = Try_int(2) >>> a + b 3
关于反运算我这里举一个例子,
1 class Nint(int): 2 def __radd__(self, other): 3 return int.__sub__(self,other) 4 5 c = Nint(5) 6 d = Nint(3) 7 print(a+b) #-2
所以在重写反运算魔法方法的时候,一定要注意顺序问题。
2、增量赋值运算
python也有大量的魔法方法可以定制增量赋值语句,增量赋值其实就是一种能偷懒的形式,它将操作符与赋值的形式结合起来,例如
>>> a = a + b #一般形式 >>> a += b #协成增量赋值的形式
3、一元操作符
一元操作符就是只有一个操作数的意思,像a+b这样,加号左右有a.b两个操作数,叫做二元操作符。只有一个操作数的,例如把剑豪放在一个操作数的前边,就是取这个操作数的相反数的意思,这个时候管它叫负号。
python支持的一元操作符主要有__neg__()(表示正号),__pos__()(定义负号),__abs__()(定义当被__abs__()调用时取绝对值的意思),__invert__()(定义按位取反)