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秒
结束计时。。。

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

 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__

结果:

>>> 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分钟‘
 

原文地址:https://www.cnblogs.com/pinpin/p/9905980.html

时间: 2024-10-11 12:36:01

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

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

魔法方法总是被双下划线包围,例如:__init__() 魔法方法是面向对象的python的一切,它的魔力体现在总能在合适的时候调用. 先来介绍析构和构造的三个魔法方法: __init__():构造方法,类在实例化成对象的时候会首先调用这个方法(可选)__new__():才是在一个对象实例化的时候所调用的一个方法,与其他魔方方法不同,它的第一个参数是cls(类),其他参数会传给__init__()__del__():如果说__init__()和__new__()是对象的构造器话,__del__()

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

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

python中魔法方法__str__与__repr__的区别

提出问题 当我们自定义一个类时,打印这个类对象或者在交互模式下直接输入这个类对象按回车,默认显示出来的信息好像用处不大.如下所示 In [1]: class People: ...: def __init__(self, name, sex): ...: self.name = name ...: self.sex = sex ...: In [2]: p = People('xiaoming', 'male') In [3]: p Out[3]: <__main__.People at 0x7

python_面向对象魔法方法指南

原文: http://www.rafekettler.com/magicmethods.html 原作者: Rafe Kettler 翻译: hit9 原版(英文版) Repo: https://github.com/RafeKettler/magicmethods Contents (译)Python魔法方法指南 简介 构造方法 操作符 比较操作符 数值操作符 一元操作符 常见算数操作符 反射算数运算符 增强赋值运算符 类型转换操作符 类的表示 访问控制 自定义序列 预备知识 容器背后的魔法方

python 的特殊方法 __str__和__repr__

__str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __str__(self): return '(Person: %s, %s)' % (self.name, self.gender) 现在,在交互式命令行下用 print 试试: >>>

python类中方法__str__()和__repr__()简单粗暴总结

在交互式模式下,类中同时实现__str__()和__repr__()方法: 直接输入实例名称显示repr返回的类容: 用print打印实例名称显示str返回的内容: >>> class Test: ... def __repr__(self): ... return 'Test -> return repr' ... def __str__(self): ... return 'Test -> return str' ... >>> t = Test() &

python面向对象高级:反射、魔法方法、元类

自省/反射什么是反射?自省也称作反射,这个性质展示了某对象是如何在运行期取得自身信息的.并且在python里,反射可以使得程序运行时对象拥有增删改查它本身属性或行为的一种能力如果Python不支持某种形式的自省功能,dir和type内建函数,将很难正常工作.还有那些特殊属性,像__dict__,__name__及__doc__反射的使用场景? 即插即用,即可以事先定义好接口,接口只有在被完成后才会真正执行 比如:如果和别人共同合作开发项目,但是需要用到对方的类的方法,对方还没完成 f1=FtpC

python进阶之内置函数和语法糖触发魔法方法

前言 前面已经总结了关键字.运算符与魔法方法的对应关系,下面总结python内置函数对应的魔法方法. 魔法方法 数学计算 abs(args):返回绝对值,调用__abs__; round(args):返回四舍五入的值,调用__round__; math.floor():向下取整,调用__floor__; math.ceil():向上取整,调用__ceil__; math.trunc():求一个值距离0最近的整数,调用__trunc__; divmod(a,b):返回商和余,调用__divmod_

python魔法方法详解

文章来源:http://blog.csdn.net/koko66/article/details/42709279 据说,Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切. 他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的. Python 的魔术方法非常强大,然而随之而来的则是责任.了解正确的方法去使