使用魔法方法可以简化我们的代码,给我们带来很多 方便 。
构造与析构
1、__init__(self,[x,.....])
返回值是None,只有我们需要初始化的时候我们才用这个方法
>>> class Rectange:
def __init__(self,x,y):
self.x = x
self.y = y
def getperi(self):
return (self.x + self.y)*2
def getarea(self):
return (self.x * self.y)
>>> rect = Rectange(3,4)
>>> rect.getperi()
14
>>> rect.getarea()
12
>>>
2、__new__(cls[, ....])
一般我们很少重写,但是当继承一个不可变类型但是又要修改的时候就会重写这个方法
>>> class CapStr(str):
def __new__(cls,string):
string = string.upper()
return str.__new__(cls,string)
>>> a = CapStr('xiaoyi nihao')
>>> a
'XIAOYI NIHAO'
>>>
3、__del__(self)将对对象进行删除的时候
>>> class C:
def __init__(self):
print('我是init方法')
def __del__(self):
print('我是 del方法')
>>> c1 =C()
我是init方法
>>> c2=c1
>>> del c2
>>> del c1
我是 del方法
>>>
算术运算
下面列举一些常用的算术运算魔法方法:
__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]) | 定义当pow()调用或**运算时 的行为 |
__lshift__(self , other) | 定义按位左移的行为:<< |
__rshift__(self , other) | 定义按位右移的行为:>> |
__and__(self , other) | 定义按位与操作的行为:& |
__xor__(self , other) | 定义按位异或的行为:^ |
__or__(self, other) | 定义按位或操作的行为:| |
这里我就简单的举一个例子:
>>> class C(int):
def __add__(self,other):
return int.__add__(self,other)
>>> a= C(6)
>>> b= C(5)
>>> a+b
11
>>>
反运算:
__radd__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rsub__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rmul__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rtruediv__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rfloordiv__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rmod__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rdivmod__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rpow__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rlshift__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rrshift__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rand__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__rxor__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
__ror__(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
这里简单的举一个例子:
>>> class int(int):
def __add__(self,other):
return int.__sub__(self,other)
>>> a=int(5)
>>> b=int('6')
>>> a+b
-1
>>> 1+b
7
>>>
增量赋值运算:
__iadd__(self, other) | 定义赋值加法的行为:+= |
__isub__(self, other) | 定义赋值减法的行为:-= |
__imul__(self, other) | 定义赋值乘法的行为:*= |
__itruediv__(self, other) | 定义赋值真除法的行为:/= |
__ifloordiv__(self, other) | 定义赋值整数除法的行为://= |
__imod__(self, other) | 定义赋值取模算法的行为:%= |
__ipow__(self, other[, modulo]) | 定义赋值幂运算的行为:**= |
__ilshift__(self, other) | 定义赋值按位左移位的行为:<<= |
__irshift__(self, other) | 定义赋值按位右移位的行为:>>= |
__iand__(self, other) | 定义赋值按位与操作的行为:&= |
__ixor__(self, other) | 定义赋值按位异或操作的行为:^= |
__ior__(self, other) | 定义赋值按位或操作的行为:|= |
一元操作符 :
__pos__(self) | 定义正号的行为:+x |
__neg__(self) | 定义负号的行为:-x |
__abs__(self | 定义当被 abs() 调用时的行为 |
__invert__(self) | 定义按位求反的行为:~x |
下面运用一下上面说过的知识完成一个小功能:
时间元祖(time.struct_time):
gmtime(),localtime() 和 strptime() 以时间元祖(struct_time)的形式返回。
索引值(Index) | 属性(Attribute) | 值(Values) |
0 | tm_year(年) | (例如:2015) |
1 | tm_mon(月 | 1 ~ 12 |
2 | tm_mday(日) | 1 ~ 31 |
3 | tm_hour(时 | 0 ~ 23 |
4 | tm_min(分) | 0 ~ 59 |
5 | tm_sec(秒) | 0 ~ 61(见下方注1) |
6 | tm_wday(星期几) | 0 ~ 6(0 表示星期一) |
7 | tm_yday(一年中的第几天) | 1 ~ 366 |
8 | tm_isdst(是否为夏令时) | 0, 1, -1(-1 代表夏令时) |
注1:范围真的是 0 ~ 61(你没有看错哦^_^);60 代表闰秒,61 是基于历史原因保留。
time.localtime([secs]):
接收时间辍(1970 纪元年后经过的浮点秒数)并返回当地时间下的时间元组 t(t.tm_isdst 可取 0 或 1,取决于当地当时是不是夏令时)
更多关于time模块的内容请参考:https://fishc.com.cn/forum.php?mod=viewthread&tid=51326&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
关于重写的两个知识举例:
>>> class A():
def __str__(self):
return 'xiaoyi'
>>> a= A()
>>> print(a)
xiaoyi
>>> class B():
def __repr__(self):
return 'xiaoyi hello'
>>> b= B()
>>> b
xiaoyi hello
>>>
下面看一下整个功能的代码:
import time as t
class Mytimer():
def __init__(self):
self.unit = ['年','月','天 ','小时','分钟','秒 ']
self.prompt= '未开始计时'
self.begin = 0
self.end = 0
self.lasted = []
def __str__(self):
return self.prompt
__repr__ = __str__
#开始计时
def start(self):
self.begin = t.localtime()
self.prompt= '提示:请先调用停止'
print('计时开始 。。。')
#停止计时
def stop(self):
if not self.begin:
print('提示: 请先调用 开始')
self.end = t.localtime()
self._calc()
print('计时停止。。。')
#内部方法计算时间
def _calc(self):
self.lasted = []
self.prompt = '总共运行了'
for index in range(6):
self.lasted.append(self.end[index] - self.begin[index])
if self.lasted[index]:
self.prompt += str(self.lasted[index])+ self.unit[index]
#为下一轮做准备
self.begin = 0
self.end = 0
print(self.prompt)