使用python的魔法方法和time模块定制一个计时器的类

  1. 1.time模块里的localtime()方法获取时间
    2.time.localtime返回struct_time格式
    3.表现你的类:__str__()和__repr__()
    先来看下__str__()和__repr__()魔法方法
  1. >>> class A():
  2. def __str__(self):
  3. return "我在学习python"
  4.  
  5. >>> a = A()
  6. >>> print(a)
  7. 我在学习python
  8. >>> a
  9. <__main__.A object at 0x0000000002F6AB70>
  10. >>> class B():
  11. def __repr__(self):
  12. return "python要一起学习的"
  13.  
  14. >>> b = B()
  15. >>> b
  16. python要一起学习的
  17. >>> print(b)
  18. python要一起学习的

看到这里知道要怎么写了吗,如果还是比较蒙的,那就继续往下看吧

首先用到一个time模块,我们先导入time模块

其次是两个功能,一个是开始时间,一个是结束时间:

  1. >>> import time as t
  2. >>> class MyTimer():
  3. def start(self):
  4. self.start = t.localtime()
  5. print("计时开始。。。")
  6. def stop(self):
  7. self.stop = t.localtime()
  8. self.__calc()
  9. print("结束计时。。。")
  10. def __calc(self):
  11. self.lasted = []
  12. self.prompt ="总共运行了"
  13. for index in range(6):
  14. self.lasted.append(self.stop[index] - self.start[index])
  15. self.prompt += str(self.lasted[index])
  16. print(self.prompt)
  17.  
  18. >>> t1 = MyTimer()
  19. >>> t1.start()
  20. 计时开始。。。
  21. >>> t1.stop()
  22. 总共运行了000008
  23. 结束计时。。。

基本功能已经实现了,下面需要完成的是print(t1)和直接调用t1均显示结果,那就需要重写__str__()和__repr__()魔法方法完成。

  1. def __str__(self):
  2. return self.prompt
  3. __repr__ = __str__

来我们加上运行看下效果

  1. >>> import time as t
  2. >>> class MyTimer():
  3. def start(self):
  4. self.start = t.localtime()
  5. print("计时开始。。。")
  6. def stop(self):
  7. self.stop = t.localtime()
  8. self.__calc()
  9. print("结束计时。。。")
  10. def __calc(self):
  11. self.lasted = []
  12. self.prompt ="总共运行了"
  13. for index in range(6):
  14. self.lasted.append(self.stop[index] - self.start[index])
  15. self.prompt += str(self.lasted[index])
  16. print(self.prompt)
  17. def __str__(self):
  18. return self.prompt
  19. __repr__ = __str__
  20.  
  21. >>> t1 = MyTimer()
  22. >>> t1.start()
  23. 计时开始。。。
  24. >>> t1.stop()
  25. 总共运行了000007
  26. 结束计时。。。
  27. >>> t1
  28. 总共运行了000007

很不错的,但是,如果用户不按常理出牌,直接调用t1,那就报错了

  1. >>> t1 = MyTimer()
  2. >>> t1
  3. Traceback (most recent call last):
  4. File "<pyshell#57>", line 1, in <module>
  5. t1
  6. File "C:\Python36\lib\idlelib\rpc.py", line 617, in displayhook
  7. text = repr(value)
  8. File "<pyshell#51>", line 17, in __str__
  9. return self.prompt
  10. AttributeError: 'MyTimer' object has no attribute 'prompt'

来我们先分析下,当直接执行t1的时候,python会调用__str__()魔法方法,但他却没有prompt属性。prompt属性在__calc()方法就没有被调用到,所以也就没有prompt属性的定义了。

需要解决这个问题,需要用到在类里用到最多的方法__init__(),所有属于实例对象的变量只要在这里先定义,就不会出现这样的问题了

  1. >>> import time as t
  2. >>> class MyTimer():
  3. def __init__(self):
  4. self.prompt = '未开始计时'
  5. self.lasted = 0
  6. self.start = 0
  7. self.stop = 0
  8. def start(self):
  9. self.start = t.localtime()
  10. print("计时开始。。。")
  11. def stop(self):
  12. self.stop = t.localtime()
  13. self.__calc()
  14. print("结束计时。。。")
  15. def __calc(self):
  16. self.lasted = []
  17. self.prompt ="总共运行了"
  18. for index in range(6):
  19. self.lasted.append(self.stop[index] - self.start[index])
  20. self.prompt += str(self.lasted[index])
  21. print(self.prompt)
  22. def __str__(self):
  23. return self.prompt
  24. __repr__ = __str__
  25.  
  26. >>> t1 = MyTimer()
  27. >>> t1
  28. 未开始计时
  29. >>> t1.start()
  30. Traceback (most recent call last):
  31. File "<pyshell#71>", line 1, in <module>
  32. t1.start()
  33. TypeError: 'int' object is not callable

这里跑出的错误,异常是:

  1. TypeError: 'int' object is not callable。在调用start()方法的时候报错,看一下是不是在__init__()方法里定义的self.start的变量和类中的方法名属性同名,属性会被覆盖方法。所以这就是问题所在,那就修改过来吧,吧self.startself.stop改成self.beginself.end,这样程序就没有问题了,但是现实时间为000007这样还是不太人性化,然后我们需要哪找年月日,值为0时不显示的原则,让人看着舒服
  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. def start(self):
  10. self.begin = t.localtime()
  11. print("计时开始。。。")
  12. def stop(self):
  13. self.end= t.localtime()
  14. self.__calc()
  15. print("结束计时。。。")
  16. def __calc(self):
  17. self.lasted = []
  18. self.prompt ="总共运行了"
  19. for index in range(6):
  20. self.lasted.append(self.end[index] - self.begin[index])
  21. self.prompt += (str(self.lasted[index]) + self.unit[index])
  22. print(self.prompt)
  23. def __str__(self):
  24. return self.prompt
  25. __repr__ = __str__
  26.  
  27. >>> t1 = MyTimer()
  28. >>> t1.start()
  29. 计时开始。。。
  30. >>> t1.stop()
  31. 总共运行了0000小时0分钟5
  32. 结束计时。。。

看似可以了,在加上一些温馨提示的就很好了,总程序

  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__

结果:

  1. >>> t1 = MyTimer()
  2. >>> t1
  3. 未开始计时
  4. >>> t1.stop()
  5. 提示:请先调用start()开始计时
  6. >>> t1.start()
  7. 计时开始。。。
  8. >>> t1
  9. 提示;请先调用stop()结束计时
  10. >>> t1.stop
  11. <bound method MyTimer.stop of 提示;请先调用stop()结束计时>
  12. >>> t1.stop()
  13. 总共运行了1分钟
  14. 结束计时。。。
  15. >>> t1
  16. 总共运行了1分钟>>> t2 = MyTimer()
  17. >>> t2.start()
  18. 计时开始。。。
  19. >>> t2.stop()
  20. 总共运行了5
  21. 结束计时。。。
  22. >>> t2
  23. 总共运行了5
  24. >>> t1+t2
  25. '总共运行了1分钟'
  1.  

python_魔法方法(三):__str__()和__repr__()的更多相关文章

  1. Python进阶-XVIV 类的内置方法:__str__ 、__repr__、析构函数(__del__)、双下的call,eq,new,hash 以及item相关的三个方法

    类的内置方法 它与内置函数有紧密的联系,有的内置函数就是调用的内置方法. 在顶级父类obj中有: 两个双下方法 obj.__str__ str(obj) obj.__repr__ repr(obj) ...

  2. 《Python》反射、内置方法(__str__,__repr__)

    一.反射 通过字符串的形式操作对象相关的属性.(使用字符串数据类型的变量名来获取这个变量的值) Python中的一切事物都是对象(都可以使用反射) 反射类中的变量 反射对象中的变量 反射模板中的变量 ...

  3. 零基础学习python_魔法方法(41-48课)(迭代器)

    接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...

  4. python中魔法方法__init__,__str__,__del__的详细使用方法

    1. python中的魔法方法, 类似__init__, __str__等等,这些内置好的特定的方法进行特定的操作时会自动被调用 2. __init__的使用方法 class 类名(object):  ...

  5. python_魔法方法(五):描述符和定制序列

    描述符(property的原理) 描述符(descripto),用一句话来解释,描述符就是某种特殊的类的实例指派给另一个类的属性.那么什么是特殊类型的类呢?就是至少要在这个类中定义__get__(). ...

  6. python_魔法方法(一):构造和析构

    魔法方法总是被双下划线包围,例如:__init__() 魔法方法是面向对象的python的一切,它的魔力体现在总能在合适的时候调用. 先来介绍析构和构造的三个魔法方法: __init__():构造方法 ...

  7. python_魔法方法(六):迭代器和生成器

    迭代器 自始至终,都有一个概念一直在用,但是我们却没来都没有人在的深入剖析它.这个概念就是迭代. 迭代的意思有点类似循环,每一次的重复的过程被称为迭代的过程,而每一次迭代得到的结果会被用来作为下一次迭 ...

  8. python_魔法方法(四):属性访问

    通常可以通过点(.)操作符的形式去访问对象的属性,也可以通过BIF适当地去访问属性,看个例子吧 >>> class A(): def __init__(self): self.x = ...

  9. python_魔法方法(二):算术运算

    python2.2之后,对类和类型做了同意,将int().float().str().list().touple()这些BIF转换为工厂函数 >>> type(len) <cl ...

随机推荐

  1. JS性能之setTimeout与clearTimeout

    测试环境: chrome浏览器 结论: 1 一个页面用setTimeout越多,该页面消耗的内存就会越多,几乎成正比. 2 在'startCount(1000000);-->100万'情况下,不 ...

  2. 洛谷【P1236】算24点

    我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html 题目传送门:https://www.luogu.org/problemnew/show/P ...

  3. iOS获取设备型号的方法

    1. [UIDevice currentDevice].model   自己写的看只抓到模拟器和iPhone.暂时不推荐. 2.自己写的找的方法再添加.直接  NSString * deviceMod ...

  4. UVA624(01背包记录路径)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  5. Python:extend和append的用法

    转于:https://www.cnblogs.com/subic/p/6553187.html 博主:subic 1)list.append(object) 向列表中添加一个对象object2)lis ...

  6. 杂项:Code(开源资源)

    ylbtech-杂项:Code(开源资源) 1.返回顶部 1.CSDN http://code.csdn.net/ 2.腾讯·开源 http://code.tencent.com/ 3. 4. 5. ...

  7. linux->windows主动推送文件同步目录数据 linux-windows数据目录同步

    1 .windows下安装openssh for windows工具,下载地址 https://www.mls-software.com/opensshd.html 2.修改openssh安装目录下e ...

  8. python中报中文编码异常,Non-ASCII ,but no encoding declared

    异常信息: SyntaxError: Non-ASCII character '\xe5' in file a.py on line 9, but no encoding declared; see ...

  9. Java探索之旅(3)——选择与循环

    1.选择结构与输出 ❶Switch语句: Switch表达式必须算出 char,byte,short,int类型数值之一,总是括号括住:Value1----ValueN,对应有相同数据类型且为常量或者 ...

  10. Linux6.7 安装图文

    Linux6.7 安装图文 选择第一个进行安装 1.  Install or upgrade an existing system   安装或升级系统 2.  Install system with ...