使用python的魔法方法和time模块定制一个计时器的类
1.用time模块里的localtime()方法获取时间
2.time.localtime返回struct_time格式
3.表现你的类:__str__()和__repr__()
先来看下__str__()和__repr__()魔法方法
>>> classA():def __str__(self):return "我在学习python"
>>> a =A()>>> print(a)
我在学习python>>>a<__main__.a object at>
>>> classB():def __repr__(self):return "python要一起学习的"
>>> b =B()>>>b
python要一起学习的>>> print(b)
python要一起学习的
看到这里知道要怎么写了吗,如果还是比较蒙的,那就继续往下看吧
首先用到一个time模块,我们先导入time模块
其次是两个功能,一个是开始时间,一个是结束时间:
>>> importtime as t>>> classMyTimer():defstart(self):
self.start=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__
来我们加上运行看下效果
>>> importtime as t>>> classMyTimer():defstart(self):
self.start=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__
>>> t1 =MyTimer()>>>t1.start()
计时开始。。。>>>t1.stop()
总共运行了000007
结束计时。。。>>>t1
总共运行了000007
很不错的,但是,如果用户不按常理出牌,直接调用t1,那就报错了
>>> t1 =MyTimer()>>>t1
Traceback (most recent call last):
File"", line 1, in t1
File"C:\Python36\lib\idlelib\rpc.py", line 617, indisplayhook
text=repr(value)
File"", line 17, in __str__
returnself.prompt
AttributeError:'MyTimer' object has no attribute 'prompt'
来我们先分析下,当直接执行t1的时候,python会调用__str__()魔法方法,但他却没有prompt属性。prompt属性在__calc()方法就没有被调用到,所以也就没有prompt属性的定义了。
需要解决这个问题,需要用到在类里用到最多的方法__init__(),所有属于实例对象的变量只要在这里先定义,就不会出现这样的问题了
>>> importtime as t>>> classMyTimer():def __init__(self):
self.prompt= '未开始计时'self.lasted=0
self.start=0
self.stop=0defstart(self):
self.start=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__
>>> t1 =MyTimer()>>>t1
未开始计时>>>t1.start()
Traceback (most recent call last):
File"", line 1, in 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时不显示的原则,让人看着舒服
>>> importtime as t>>> classMyTimer():def __init__(self):
self.unit=['年','月','天','小时','分钟','秒']
self.prompt= '未开始计时'self.lasted=[]
self.begin=0
self.end=0defstart(self):
self.begin=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__
>>> t1 =MyTimer()>>>t1.start()
计时开始。。。>>>t1.stop()
总共运行了0年0月0天0小时0分钟5秒
结束计时。。。
看似可以了,在加上一些温馨提示的就很好了,总程序
1 importtime as t2 classMyTimer():3 def __init__(self):4 self.unit =['年','月','天','小时','分钟','秒']5 self.prompt = '未开始计时'
6 self.lasted =[]7 self.begin =08 self.end =09
10 #开始计时
11 defstart(self):12 self.begin =t.localtime()13 self.prompt = "提示;请先调用stop()结束计时"
14 print("计时开始。。。")15
16 #停止计时
17 defstop(self):18 if notself.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 ifself.lasted[index]:32 self.prompt += (str(self.lasted[index]) +self.unit[index])33 #为下一计算初始化变量
34 self.begin =035 self.end =036 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 ifresult[index]:44 prompt += (str(self.lasted[index]) +self.unit[index])45 returnprompt46
47 def __str__(self):48 returnself.prompt49 __repr__ = __str__
结果:
>>> t1 =MyTimer()>>>t1
未开始计时>>>t1.stop()
提示:请先调用start()开始计时>>>t1.start()
计时开始。。。>>>t1
提示;请先调用stop()结束计时>>>t1.stop
>>>t1.stop()
总共运行了1分钟结束计时。。。>>>t1
总共运行了1分钟>>> t2 =MyTimer()>>>t2.start()
计时开始。。。>>>t2.stop()
总共运行了5秒
结束计时。。。>>>t2
总共运行了5秒>>> t1+t2'总共运行了1分钟'