042魔法方法:算术运算
自python2.2以后,对类和类型进行了统一,
做法就是将int(),float(),str(),list(),tuple()转为工厂函数
工厂函数:就是一个对象,当你调用它们的时候,事实上就是创建一个相应的实例对象
如:>>>a = int('123')
>>>b = int('456')
>>>a + b
579
a和b是工厂函数(类对象),int的实例对象
对象a和b相加的时候会自动调用__add__魔法函数
算术运算对应的魔法函数:
__add__(self,other) 定义加法的行为:+
__sub__(self,other) 定义减法的行为:-
__mul__(self,other) 定义乘法的行为:*
__truediv__(self,other) 定义真除法的行为:/
__floordiv__(self,other) 定义整数除法的行为://
__mod__(self,other) 定义取模运算的行为:%
__divmod__(self,other) 定义被divmod()调用时的行为
__pow__(self,other[,modulo])定义被power()调用或**运算时的行为
__lshift__(self,other) 定义按位左移的行为:<<
__rshift__(self,other) 定义按位右移的行为:>>
__add__(self,other) 定义加法的行为:&
__xor__(self,other) 定义加法的行为:^
__or__(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+b
-2
>>> a-b
8
如果返回时不调用int的魔法方法可以吗?
>>> class New_int(int):
... def __add__(self,other):
... return self + other
... def __sub__(self,other):
... return self - other
...
>>> a = New_int(3)
>>> b = New_int(5)
>>> a + b 会无限递归,然后退出
File "<stdin>", line 3, in __add__
............
File "<stdin>", line 3, in __add__
RuntimeError: 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(3)
>>> b = Try_int(5)
>>> a + b
>>>8
练习:
1. python中可以实现两个字符串相加自动拼接,但两个字符串相减却抛出异常
现在定义一个Nstr类,支持:A-B:从A中除去所有B的子字符串
如:>>> class Nstr(str):
... def __sub__(self,other):
... return self.replace(other,'')
...
>>> a = Nstr("123aaa")
>>> b = Nstr("a")
>>> a - b
'123'
重载__sub__魔法方法即可
2. 移位操作符应用二进制操作数,定义一个新的类Nstr,也支持以为操作符的运算
如:>>> class Nstr(str):
... def __lshift__(self,other):
... return self[other:] + self[:other]
... def __rshift__(self,other):
... return self[:-other] + self[-other:]
...
>>> a = Nstr('I love you!')
>>> a << 3
'ove you!I l'
>>> a >> 3
'I love you!'
3. 定义一个类Nstr,当类的实例对象发生+-*/时,将对象的所有字符串的ASCII码之和进行计算。
>>> class Nstr(int):
... def __new__(cls,arg=0):
... if isinstance(arg,str):
... total = 0
... for each in arg:
... total += ord(each)
... arg = total
... return int.__new__(cls,arg)
...
>>> a = Nstr('I')
>>> b = Nstr('LOVE')
>>> c = Nstr('YOU')
>>> a + b + c
636