python_魔法方法(三):__str__()和__repr__()
使用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__()的更多相关文章
- Python进阶-XVIV 类的内置方法:__str__ 、__repr__、析构函数(__del__)、双下的call,eq,new,hash 以及item相关的三个方法
类的内置方法 它与内置函数有紧密的联系,有的内置函数就是调用的内置方法. 在顶级父类obj中有: 两个双下方法 obj.__str__ str(obj) obj.__repr__ repr(obj) ...
- 《Python》反射、内置方法(__str__,__repr__)
一.反射 通过字符串的形式操作对象相关的属性.(使用字符串数据类型的变量名来获取这个变量的值) Python中的一切事物都是对象(都可以使用反射) 反射类中的变量 反射对象中的变量 反射模板中的变量 ...
- 零基础学习python_魔法方法(41-48课)(迭代器)
接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...
- python中魔法方法__init__,__str__,__del__的详细使用方法
1. python中的魔法方法, 类似__init__, __str__等等,这些内置好的特定的方法进行特定的操作时会自动被调用 2. __init__的使用方法 class 类名(object): ...
- python_魔法方法(五):描述符和定制序列
描述符(property的原理) 描述符(descripto),用一句话来解释,描述符就是某种特殊的类的实例指派给另一个类的属性.那么什么是特殊类型的类呢?就是至少要在这个类中定义__get__(). ...
- python_魔法方法(一):构造和析构
魔法方法总是被双下划线包围,例如:__init__() 魔法方法是面向对象的python的一切,它的魔力体现在总能在合适的时候调用. 先来介绍析构和构造的三个魔法方法: __init__():构造方法 ...
- python_魔法方法(六):迭代器和生成器
迭代器 自始至终,都有一个概念一直在用,但是我们却没来都没有人在的深入剖析它.这个概念就是迭代. 迭代的意思有点类似循环,每一次的重复的过程被称为迭代的过程,而每一次迭代得到的结果会被用来作为下一次迭 ...
- python_魔法方法(四):属性访问
通常可以通过点(.)操作符的形式去访问对象的属性,也可以通过BIF适当地去访问属性,看个例子吧 >>> class A(): def __init__(self): self.x = ...
- python_魔法方法(二):算术运算
python2.2之后,对类和类型做了同意,将int().float().str().list().touple()这些BIF转换为工厂函数 >>> type(len) <cl ...
随机推荐
- Oracle12c多租户如何连接到CDB或PDB、CDB与PDB容器切换
Oracle 数据库 12 c 多租户选项允许单个容器数据库 (CDB) 来承载多个单独的可插拔数据库 (PDB).那么我们如何连接到容器数据库 (CDB) 和可插拔数据库 (PDB). 1. V$S ...
- Django_form补充
问题1: 注册页面输入为空,报错:keyError:找不到password def clean(self): print("---",self.cleaned_data) ...
- swift-get-nodes简单使用
在参考http://blog.csdn.net/cywosp/article/details/12850645文章对对象的具体物理磁盘位置进行查找时,发现两个问题: 1. 在使用swift+keyst ...
- TS学习之Symbol
symbol成为了一种新的原生类型,就像number和string一样(意思是可以像string一样,作为对象的属性等) Symbols是不可改变且唯一的 //symbol通过Symbol函数构造,但 ...
- JS开发中的一些小技巧和方法
生成指定范围内的随机数 当我们需要获取指定范围(min,max)内的整数的时候,下面的代码非常适合:这段代码用的还挺多的. function setRadomNum(min,max){ return ...
- 使用jquery扩展表格行合并方法探究
1.前言 最近项目中用到一个表格中对于相同内容的数据进行行合并的需求,本来想从网上找个现成的,省的自己再造轮子.于是就开始谷歌了...不过在搜索的过程中,发现找到的工具类很多都有一个前提,就是该表格中 ...
- linux strace-跟踪进程的系统调用或是信号产生情况,lstrace-跟踪己丑年调用库函数情况,进程跟踪调试命令
本工具可以用来做大多数排除,比如mount一个NFS,很慢,找不出原因,我们可以使用strace命令来跟中mount这个经常所有的调用过程. strace 命令是一种强大的工具,它能够显示所有由用户空 ...
- 【总结整理】overflow: auto/hidden;清除自己
.top-nav{ font-size: 12px; font-weight: bold; list-style-type: none; border-bottom: 8px solid #DC4E1 ...
- layui 文件上传加进度条
1.页面 <div class="layui-row layui-col-space5"> <div class="layui-form-item&qu ...
- Could not get lock /var/lib/dpkg/lock - open 解决方法
无法获得锁 /var/lib/dpkg/lock E: Could not get lock /var/lib/dpkg/lock - open (11 Resource temporarily un ...