使用python的魔法方法和time模块定制一个计时器的类
1.用time模块里的localtime()方法获取时间
2.time.localtime返回struct_time格式
3.表现你的类:__str__()和__repr__()
先来看下__str__()和__repr__()魔法方法
>>> class A(): def __str__(self): return "我在学习python" >>> a = A() >>> print(a) 我在学习python >>> a <__main__.A object at 0x0000000002F6AB70> >>> class B(): def __repr__(self): return "python要一起学习的" >>> b = B() >>> b python要一起学习的 >>> print(b) python要一起学习的
看到这里知道要怎么写了吗,如果还是比较蒙的,那就继续往下看吧
首先用到一个time模块,我们先导入time模块
其次是两个功能,一个是开始时间,一个是结束时间:
>>> import time as t >>> class MyTimer(): 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 = MyTimer() >>> t1.start() 计时开始。。。 >>> t1.stop() 总共运行了000008 结束计时。。。
基本功能已经实现了,下面需要完成的是print(t1)和直接调用t1均显示结果,那就需要重写__str__()和__repr__()魔法方法完成。
def __str__(self): return self.prompt __repr__ = __str__
来我们加上运行看下效果
>>> import time as t >>> class MyTimer(): 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 = MyTimer() >>> t1.start() 计时开始。。。 >>> t1.stop() 总共运行了000007 结束计时。。。 >>> t1 总共运行了000007
很不错的,但是,如果用户不按常理出牌,直接调用t1,那就报错了
>>> t1 = MyTimer() >>> t1 Traceback (most recent call last): File "<pyshell#57>", line 1, in <module> t1 File "C:Python36libidlelib pc.py", line 617, in displayhook text = repr(value) File "<pyshell#51>", line 17, in __str__ return self.prompt AttributeError: 'MyTimer' object has no attribute 'prompt'
来我们先分析下,当直接执行t1的时候,python会调用__str__()魔法方法,但他却没有prompt属性。prompt属性在__calc()方法就没有被调用到,所以也就没有prompt属性的定义了。
需要解决这个问题,需要用到在类里用到最多的方法__init__(),所有属于实例对象的变量只要在这里先定义,就不会出现这样的问题了
>>> import time as t >>> class MyTimer(): def __init__(self): self.prompt = '未开始计时' self.lasted = 0 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 = MyTimer() >>> t1 未开始计时 >>> t1.start() Traceback (most recent call last): File "<pyshell#71>", line 1, in <module> t1.start() TypeError: 'int' object is not callable
这里跑出的错误,异常是:
TypeError: 'int' object is not callable。在调用start()方法的时候报错,看一下是不是在__init__()方法里定义的self.start的变量和类中的方法名属性同名,属性会被覆盖方法。所以这就是问题所在,那就修改过来吧,吧self.start和self.stop改成self.begin和self.end,这样程序就没有问题了,但是现实时间为000007这样还是不太人性化,然后我们需要哪找年月日,值为0时不显示的原则,让人看着舒服
>>> import time as t >>> class MyTimer(): def __init__(self): self.unit =['年','月','天','小时','分钟','秒'] self.prompt = '未开始计时' self.lasted = [] self.begin = 0 self.end = 0 def start(self): self.begin = t.localtime() print("计时开始。。。") def stop(self): 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]) self.prompt += (str(self.lasted[index]) + self.unit[index]) print(self.prompt) def __str__(self): return self.prompt __repr__ = __str__ >>> t1 = MyTimer() >>> t1.start() 计时开始。。。 >>> t1.stop() 总共运行了0年0月0天0小时0分钟5秒 结束计时。。。
看似可以了,在加上一些温馨提示的就很好了,总程序
1 import time as t 2 class MyTimer(): 3 def __init__(self): 4 self.unit =['年','月','天','小时','分钟','秒'] 5 self.prompt = '未开始计时' 6 self.lasted = [] 7 self.begin = 0 8 self.end = 0 9 10 #开始计时 11 def start(self): 12 self.begin = t.localtime() 13 self.prompt = "提示;请先调用stop()结束计时" 14 print("计时开始。。。") 15 16 #停止计时 17 def stop(self): 18 if not self.begin: 19 print("提示:请先调用start()开始计时") 20 else: 21 self.end = t.localtime() 22 self.__calc() 23 print("结束计时。。。") 24 25 #计算运行时间 26 def __calc(self): 27 self.lasted = [] 28 self.prompt ="总共运行了" 29 for index in range(6): 30 self.lasted.append(self.end[index] - self.begin[index]) 31 if self.lasted[index]: 32 self.prompt += (str(self.lasted[index]) + self.unit[index]) 33 #为下一计算初始化变量 34 self.begin = 0 35 self.end = 0 36 print(self.prompt) 37 38 def __add__(self,other): 39 prompt = "总共运行了" 40 result = [] 41 for index in range(6): 42 result.append(self.lasted[index]+other.lasted[index]) 43 if result[index]: 44 prompt += (str(self.lasted[index]) + self.unit[index]) 45 return prompt 46 47 def __str__(self): 48 return self.prompt 49 __repr__ = __str__
结果:
>>> t1 = MyTimer() >>> t1 未开始计时 >>> t1.stop() 提示:请先调用start()开始计时 >>> t1.start() 计时开始。。。 >>> t1 提示;请先调用stop()结束计时 >>> t1.stop <bound method MyTimer.stop of 提示;请先调用stop()结束计时> >>> t1.stop() 总共运行了1分钟 结束计时。。。 >>> t1 总共运行了1分钟>>> t2 = MyTimer() >>> t2.start() 计时开始。。。 >>> t2.stop() 总共运行了5秒 结束计时。。。 >>> t2 总共运行了5秒 >>> t1+t2 '总共运行了1分钟'