使用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:\Python36\lib\idlelib\rpc.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秒
结束计时。。。

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

 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()
self.prompt = "提示;请先调用stop()结束计时"
print("计时开始。。。") #停止计时
def stop(self):
if not self.begin:
print("提示:请先调用start()开始计时")
else:
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])
if self.lasted[index]:
self.prompt += (str(self.lasted[index]) + self.unit[index])
#为下一计算初始化变量
self.begin = 0
self.end = 0
print(self.prompt) def __add__(self,other):
prompt = "总共运行了"
result = []
for index in range(6):
result.append(self.lasted[index]+other.lasted[index])
if result[index]:
prompt += (str(self.lasted[index]) + self.unit[index])
return prompt def __str__(self):
return self.prompt
__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分钟'
 

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. findBug 错误修改指南

      1. EC_UNRELATED_TYPESBug: Call to equals() comparing different types Pattern id: EC_UNRELATED_TYPE ...

  2. [转] 更新Flash CS6发布设置的目标播放器版本

    目前Aodbe发布的最新版的Flash CS6,都不支持将Flash Player 11作为目标播放器版本发布.这个问题很容易解决,但涉及到的东西却比较多,我在这里将一一讲解.首先来个Setp by ...

  3. 【转】Pro Android学习笔记(十一):了解Intent(中)

    Intent的构成 Intent可以带有action,data(由URI表达),extra data(key/value map,键值对),指定的类名(成为component name).一个inte ...

  4. 如何在Windows平台使用VS搭建C++/Lua的开发环境

    转自:http://ju.outofmemory.cn/entry/95358 本文主要介绍如何在Windows平台利用VS搭建C++/Lua开发环境.这里的“C++/Lua开发环境”主要指的是C++ ...

  5. mount总结

    挂载分区 mount基本语法 mount [参数] /dev/sdb1(需要挂载的分区) /sdb1(挂载目录) 参数是可选的,也可以不带参数,参数的使用方法(-o ro,sync,atime). 参 ...

  6. python 基础 操作文件和目录

    获得当前目录路径 :os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 删除一个文件:os.remove(filename) 删除多个空目录 :os.removefir ...

  7. javascript如何判断手机是什么系统

    做H5页面的时候,经常会用到判断手机是什么系统,根据系统的型号,实现不同的效果,那么如何判断显示页面的手机型号呢? (function(){ var isMobile={ Android:functi ...

  8. java电子书chm全套下载

    链接:http://pan.baidu.com/s/1qWmMlYk 密码:us3x 版权声明:本文为博主原创文章,未经博主允许不得转载.

  9. [hdu4734]F(x)数位dp

    题意:求0~f(b)中,有几个小于等于 f(a)的. 解题关键:数位dp #include<bits/stdc++.h> using namespace std; typedef long ...

  10. C++中的构造函数小结

    对象的初始化 对象时类的实例,类是不占用空间的,对象是占用空间的. 因为类是抽象的,不占用空间的,所以我们不能再定义类的时候对对象进行初始化操作的. 但是,我们可以定义一个函数,在类实例化一个对象的时 ...