python 魔法方法str_python_魔法方法(三):__str__()和__repr__()

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

1.用time模块里的localtime()方法获取时间

2.time.localtime返回struct_time格式

3.表现你的类:__str__()和__repr__()

先来看下__str__()和__repr__()魔法方法

>>> classA():def __str__(self):return "我在学习python"

>>> a =A()>>> print(a)

我在学习python>>>a<__main__.a object at>

>>> classB():def __repr__(self):return "python要一起学习的"

>>> b =B()>>>b

python要一起学习的>>> print(b)

python要一起学习的

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

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

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

>>> importtime as t>>> classMyTimer():defstart(self):

self.start=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__

来我们加上运行看下效果

>>> importtime as t>>> classMyTimer():defstart(self):

self.start=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__

>>> t1 =MyTimer()>>>t1.start()

计时开始。。。>>>t1.stop()

总共运行了000007

结束计时。。。>>>t1

总共运行了000007

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

>>> t1 =MyTimer()>>>t1

Traceback (most recent call last):

File"", line 1, in t1

File"C:\Python36\lib\idlelib\rpc.py", line 617, indisplayhook

text=repr(value)

File"", line 17, in __str__

returnself.prompt

AttributeError:'MyTimer' object has no attribute 'prompt'

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

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

>>> importtime as t>>> classMyTimer():def __init__(self):

self.prompt= '未开始计时'self.lasted=0

self.start=0

self.stop=0defstart(self):

self.start=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__

>>> t1 =MyTimer()>>>t1

未开始计时>>>t1.start()

Traceback (most recent call last):

File"", line 1, in 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时不显示的原则,让人看着舒服

>>> importtime as t>>> classMyTimer():def __init__(self):

self.unit=['年','月','天','小时','分钟','秒']

self.prompt= '未开始计时'self.lasted=[]

self.begin=0

self.end=0defstart(self):

self.begin=t.localtime()print("计时开始。。。")defstop(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):returnself.prompt__repr__ = __str__

>>> t1 =MyTimer()>>>t1.start()

计时开始。。。>>>t1.stop()

总共运行了0年0月0天0小时0分钟5秒

结束计时。。。

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

1 importtime as t2 classMyTimer():3 def __init__(self):4 self.unit =['年','月','天','小时','分钟','秒']5 self.prompt = '未开始计时'

6 self.lasted =[]7 self.begin =08 self.end =09

10 #开始计时

11 defstart(self):12 self.begin =t.localtime()13 self.prompt = "提示;请先调用stop()结束计时"

14 print("计时开始。。。")15

16 #停止计时

17 defstop(self):18 if notself.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 ifself.lasted[index]:32 self.prompt += (str(self.lasted[index]) +self.unit[index])33 #为下一计算初始化变量

34 self.begin =035 self.end =036 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 ifresult[index]:44 prompt += (str(self.lasted[index]) +self.unit[index])45 returnprompt46

47 def __str__(self):48 returnself.prompt49 __repr__ = __str__

结果:

>>> t1 =MyTimer()>>>t1

未开始计时>>>t1.stop()

提示:请先调用start()开始计时>>>t1.start()

计时开始。。。>>>t1

提示;请先调用stop()结束计时>>>t1.stop

>>>t1.stop()

总共运行了1分钟结束计时。。。>>>t1

总共运行了1分钟>>> t2 =MyTimer()>>>t2.start()

计时开始。。。>>>t2.stop()

总共运行了5秒

结束计时。。。>>>t2

总共运行了5秒>>> t1+t2'总共运行了1分钟'

你可能感兴趣的:(python,魔法方法str)