这是我使用python写的第一个类(也算是学习面向对象语言以来正式写的第一个解耦的类),记录下改进的过程。
<>强分析需求强>
最初,因为使用时间模块显示日期时,每次都要设置时间字符串的格式,挺麻烦,但还是忍了。
后来,在处理多线程任务时需要实现定时控制的功能,更麻烦,终于决定自己做一个解决这些问题的通用代码(虽然网上有现成的模块,但亲手编写这部分代码正好能锻炼一下我的面向对象编程)。
<>强分析框架强>
刚开始,我计划做一个模仿时钟的抽象类,让它独立运行在一个线程中,让它提供显示日期,计时,设置定时任务的方法……然而由于缺乏规划、编程乱糟糟的,这些方法的代码和变量交杂在一起,难以入目,更难以扩展……气得重构代码,这次把显示日期,计时,设置定时任务三大功能分别抽象成三个类,相互解耦,各自独立运行,代码变得简洁多了。
好,旧代码就藏在git的历史记录里吧,这里贴出重构后的代码。
<>强显示时间的类强>
导入的时间 进口线程 类_Clock: ”“” 自定义的时钟类,用于获取几种不同格式的当前时间。 小数:设置time_float的精度、控制其保留几位小数。 time_diff:设置该时钟与UTC + 0时区的时差。如果不设置,会自动采用 本地时区。 ”“” def __init__(自我,name=None,小数=3,time_diff=None): self.name=名字 self.decimal=小数 自我。time_diff=time_diff 自我。time_format=" % Y/% m/H % d %: % m: % S”#时间字符串的格式 @ property def time_float(自我): ”““UTC + 0时区的时间戳,精度由self.decimal决定“”“ 返回圆(time.time (), self.decimal) @ property def time_int(自我): ”““UTC + 0时区的时间戳,精度为秒”“ 返回int (time.time ()) @ property def time_tuple(自我): ”“本地时区的时间元组”“ 如果自我。time_diff==没有: 返回time.localtime (self.time_int) 其他: 返回time.gmtime (self.time_int + self.time_diff) @ property def time_str(自我): ”“本地时间的格式化字符串“”“ 返回time.strftime(自我。time_format self.time_tuple)
<强>秒表计时的类强>
类计时器(_Clock): ”“” 自定义的计时器,像秒表一样,可以随时查看当前计时,暂停计时,继续计时。 ·创建一个计时器之后,它就会开始计时。 ·默认使用time.time()获取时间,精度为毫秒。 ·可以直接调用_Clock类的方法来获取当前时间。 ”“” def __init__(自我,* args, * * kwargs): _Clock。__init__(自我,* args, * * kwargs) 自我。记录=[]#记录每次使用的(开始时刻,暂停时刻,计时时长) 自我。状态=俺跏肌? self.go () @ property def计数(自我): ”“当前计时值“”“ 数=0 在self.record线: 如果[2]==没有行: 数+=自我。time_float行[0] 其他: 数+=线[2] self.decimal返回圆(计数) def(自我): ”“开始计时“”“ 如果自我。地位!=笆被? self.record.append(自我。time_float,没有一个,没有一个) 自我。状态="时间" def暂停(自我): ”““暂停计时“”“ #如果该计时器在计时中,就暂停它,并计算这一段的计时时长 如果自我。状态==笆被? last_line=self.record [1] self.record.remove (last_line) 当前时间=self.time_float self.record.append ( (last_line[0]、当前时间、圆(当前时间- last_line [0], self.decimal))) 自我。状态="暂停"
<强>定时任务的类强>
课程表(threading.Thread): ”“” 自定义的定时任务表,添加第一个定时任务后就创建一个线程,开始循环检查 是否执行任务表中的任务。 ·调用停止()来终止该线程。 ”“” def __init__(自我,* args, * * kwargs): threading.Thread。__init__(自我,* args, * * kwargs) 自我。_askToStop=False 自我。_schedule=[] #保存定时任务表 自我。状态=俺跏肌? def _get_time(自我): ”“”获取当前时间“”“ 返回time.time () def addTask(自我,倒计时,func * args, * * kwargs): ”“” 在任务表中增加一项定时任务:在倒计时倒计时结束之后调用 函数函数,并传入参数* args和* * kwargs。 ·定时任务只会被执行一次,执行后就会被从任务表中删除。 ·定时任务只会在倒计时结束之后被执行,但无法保证无延迟。 ”“” 如果自我。状态==俺跏肌?#第一次添加定时任务时创建一个新线程 自我。状态="运行" self.start () 任务=[] 如果isinstance(倒计时,(整数、浮点数)和倒计时祝辞0: task.append (self._get_time() +倒计时)#准备在指定时刻执行该任务 其他: 提高ValueError(““倒计时”必须是一个正整数或浮点。”) 如果调用(函数): task.append(函数) 其他: 提高ValueError(“函数必须是可调用的。”) task.append (args) #保存元组参数 task.append (kwargs) #保存字典参数 self._schedule.append(任务) self._schedule。排序(关键=λ任务:任务[0])#将任务表按时间戳的大小排的序 def _doTask(自我): ”““检查任务表中各项任务的时间,判断是否要执行它。”“ 当前时间=self._get_time () 我=0 虽然我& lt;len (self._schedule): #遍历任务表 任务=self._schedule[我] 如果任务[0]& lt;=当前时间: #如果该任务的时间不晚于当前时间,就创建一个线程去执行该任务,避免阻塞定时器线程 t1=CreatThread(任务[1],[2]*任务,* *任务[3]) t1.start () 我+=1 其他: 打破#如果该任务的时间戳大于当前时间,就提前结束遍历 德尔自我。_schedule[我]#删除过时的任务 def运行(自我): ”““线程循环运行的内容“”“ 虽然不是self._askToStop: self._doTask () #结束时进行清理 自我。状态==巴V埂? 返回0 def停止(自我): 自我。_askToStop=True 类CreatThread (threading.Thread): ”“一个简单的创建线程的类“”“ def __init__(自我、func * args, * * kwargs): threading.Thread.__init__(自我) 自我。func=函数 自我。args=参数 自我。kwargs=kwargs def运行(自我): self.func(*自我。args, * * self.kwargs)python自定义时钟类,定时任务类