(反运算相关的魔法方法)
与之前的笔记对比,不难发现反运算只是多了一个‘r’
看例子
class Nint(int): def __radd__(self,other): return int.__sub__(self,other)#加数是a,被加数是b。请问谁主动。运行后>>> a = Nint(5)>>> b = Nint(3)>>> a + b#肯定是a主动啦!8
关于反运算,这里要注意一点;对于a + b,b的__radd__(self,other),中other是a的对象,self才是b的对象
增量赋值运算符
(来源于网络)
Python里有大量的魔术方法可以定制增量赋值语句,增量赋值其实就是一种偷懒的形式,就像上面
>>> a = 1>>> b =3>>> a += b#注意+=之间无空格>>> a4>>> a = a + b
一元操作符概念
一元操作符是指一个操作数,如上面的a +=b是二元操作符,只有一个操作数的,如把一个减号放在操作数前面,取这个数相反数的意思,管他叫负号
简单的定制
#基本要求定制一个计时器额类start和stop方法代表启动计时和停止计时假设计时器对象t1,print(t1)和直接调用t1均显示结果当计时器未启动或已经停止计时,调用stop方法会给温馨提示两个计时器对象可以相加只能使用有限的资源完成
演示代码
>>>t1 = MYtime()>>>t1未开始计时>>>t1.stop()提示:请先调用start()开始计时>>>t1.start()计时开始>>>t1提示;请输入stop()结束计时>>>t1总共运行5秒>>>t2 = MYtime()>>>t2.start()计时开始>>>t2.stop()计时结束>>>t2一共运行6秒>>>t1 + t2总共运行11秒
你需要使用time模块里的localtime方法获取时间
time.localtime返回struct_time的时间格式
表现你的类__str__()和__repr__()魔法方法
>>> import time>>> time.time<built-in function time>>>> time.time()1560518311.610051>>>
localtime方法获取时间
time.localtime
>>> import time>>> time.localtime()time.struct_time(tm_year=2019, tm_mon=6, tm_mday=14, tm_hour=21, tm_min=38, tm_sec=35, tm_wday=4, tm_yday=165, tm_isdst=0)>>>
源代码
def stop(self): self.stop = t.localtime() print("计时结束") #考虑怎么进行计算localtime()返回一个时间元组的结构,只取前面6个元素,然后将stop的元素#依次减去start对应的元素,将差值存放在一个新的列表里
import time as tclass Mytime: def start(self): self.start = t.localtime() print("开始计时") def stop(self): self.stop = t.localtime() self._calc() print("计时结束") #内部方法用于计算时间 def _calc(self): self.lasted = [] self.prompt = "总共运行了" for index in range(6): self.lasted.append(self.stop[index] - self.start[index]) self.prompt += str(self.lasted[index]) print(self.prompt)
运行结果
>>> t1 = Mytime()>>> t1.start()开始计时>>> t1.stop()总共运行了000005计时结束>>>
基本实现了计时功能,接下下来需要完成print(t1)与t1均显示结果,那就要重写,str__()与__repr__()魔法方法来实现。
import time as tclass Mytime: def start(self): self.start = t.localtime() print("开始计时") def stop(self): self.stop = t.localtime() self._calc() print("计时结束") #内部方法用于计算时间 def _calc(self): self.lasted = [] self.prompt = "总共运行了" for index in range(6): self.lasted.append(self.stop[index] - self.start[index]) self.prompt += str(self.lasted[index]) print(self.prompt) def __str__(self): return self.prompt __repr__ = __str__
运行后
>>> t1 = Mytime()>>> t1.start()开始计时>>> t1.stop()总共运行了000008计时结束>>> t1总共运行了000008>>>
似乎很不错,但是一位安全工作者,怎么能把自己的用户当成“朋友”呢?
>>> t1 = Mytime()>>> t1Traceback (most recent call last): File "<pyshell#43>", line 1, in <module> t1 File "C:\Python34\lib\idlelib\rpc.py", line 614, in displayhook text = repr(value) File "C:/Users/Administrator/Desktop/fugai.py", line 19, in __str__ return self.promptAttributeError: 'Mytime' object has no attribute 'prompt'>>>
没有执行stop()那么_calc就是个摆设,要是先定义,不让在调用某个函数在进行其变量,就不会出错
import time as tclass Mytime: def __init__(self): self.prompt = "未开始计时" self.lasted = [] self.start = 0 self.stop = 0
def start(self): self.start = t.localtime() print("开始计时") def stop(self): self.stop = t.localtime() self._calc() print("计时结束") #内部方法用于计算时间 def _calc(self): self.lasted = [] self.prompt = "总共运行了" for index in range(6): self.lasted.append(self.stop[index] - self.start[index]) self.prompt += str(self.lasted[index]) print(self.prompt) def __str__(self): return self.prompt __repr__ = __str__
运行后
>>> t1 = Mytime()>>> t1未开始计时>>> t1.start()Traceback (most recent call last): File "<pyshell#46>", line 1, in <module> t1.start()TypeError: 'int' object is not callable>>>
怎么又报错了,书上是故意的,但是我是很不愿意报错,因为会浪费时间
这里简要说明
TypeError: 'int' object is not callable
大家要学会看异常,在调用t1.start()
Python认为他是个整型,这是因为如果类中的方法名(函数)和属性(变量)重名方法会覆盖属性
更改其所有self.start和self.end成self.begin和relf.start即可
但是不人性化
稍微加工一下
#记载时间模块import time as t
class Mytimer : def __init__ (self) : self.unit = ['年','月','天','时','分','秒'] self.prompt = '未开始计时' self.lasted = [] self.begin = 0 self.end = 0
#输入对象直接输出 def __str__ (self) : return self.prompt
def __repr__ (self) : return self.prompt
#开始计时模块 def start (self) : self.begin = t.localtime() self.prompt = '请先调用stop()停止计时!' print ('计时开始...')
#停止计时模块 def stop (self) : if not self.begin : print ('请先调用start()开始计时!') else : self.end = t.localtime() self._cacul() print ('计时结束!') #内部计算运行时间 def _cacul(self) : self.prompt = '总共运行了' self.lasted = [] for index in range (6) : self.lasted.append(self.end[index] - self.begin[index]) self._judge1() for index in range (6) : if self.lasted[index] : self.prompt += (str(self.lasted[index]) + str(self.unit[index])) #为下一轮计数初始化变量 self.begin = 0 self.end = 0
#计算两个时间累计和 def __add__ (self,other) : self.prompt = '两次总共运行了' self.result = [] for index in range (6) : self.result.append(self.lasted[index] + other.lasted[index]) self._judge2() for index in range (6) : if self.result [index] : self.prompt += str( self.result[index] ) + self.unit[index] return self.prompt
#判断两个数据是否出现负数 def _judge1(self) : for index in range (6) : if self.lasted[ index ] < 0 : #当负数出现时,前一位-1 self.lasted [ index-1 ] -= 1 #当负数出现在分秒时,+60 if index == 5 or index == 4: """self.lasted [ index -1 ] -= 1""" self.lasted [ index ] += 60 #当负数出现在时时,+24 elif index == 3 : """self.lasted [ index-1 ] -= 1""" self.lasted [ index ] += 24 #当负数出现在天时,+31 elif index == 2 : """self.lasted [ index-1 ] -= 1""" self.lasted [ index ] +=31 #当负数出现在月时,+12 elif index == 1 : """self.lasted [ index-1 ] -= 1""" self.lasted [ index ] += 12
#判断两个数据是或否可以进位 def _judge2 (self) : for index in range (5 , -1 , -1) : if index == 5 or index == 4 : if self.result [ index ] >= 60 : self.result [ index - 1 ] += 1 self.result [ index ] -= 60 elif index == 3 : if self.result [ index ] >= 24 : self.result [ index - 1 ] += 1 self.result [ index ] -= 24 elif index == 2 : if self.result [ index ] >= 31 : self.result [ index - 1 ] += 1 self.result [ index ] -= 31 elif index == 1 : if self.result [ index ] >= 12 : self.result [ index - 1 ] += 1 self.result [ index ] -= 12 else : pass
运行后
>>> t1 = Mytimer()>>> print(t1)未开始计时>>> t1.start()计时开始...>>> t1.stop<bound method Mytimer.stop of 请先调用stop()停止计时!>>>> t1.stop()计时结束!>>> t1总共运行了20秒>>>