反运算(简单的定制)[第十七章]

(反运算相关的魔法方法)

与之前的笔记对比,不难发现反运算只是多了一个‘r’

看例子

class Nint(int):    def __radd__(self,other):        return int.__sub__(self,other)#加数是a,被加数是b。请问谁主动。运行后>>> a = Nint(5)>>> b = Nint(3)>>> a + b#肯定是a主动啦!8

关于反运算,这里要注意一点;对于a + b,b的__radd__(self,other),中other是a的对象,self才是b的对象

增量赋值运算符

(来源于网络)

Python里有大量的魔术方法可以定制增量赋值语句,增量赋值其实就是一种偷懒的形式,就像上面

>>> a = 1>>> b =3>>> a += b#注意+=之间无空格>>> a4>>> a = a + b

一元操作符概念

一元操作符是指一个操作数,如上面的a +=b是二元操作符,只有一个操作数的,如把一个减号放在操作数前面,取这个数相反数的意思,管他叫负号

简单的定制

#基本要求定制一个计时器额类start和stop方法代表启动计时和停止计时假设计时器对象t1,print(t1)和直接调用t1均显示结果当计时器未启动或已经停止计时,调用stop方法会给温馨提示两个计时器对象可以相加只能使用有限的资源完成

演示代码

>>>t1 = MYtime()>>>t1未开始计时>>>t1.stop()提示:请先调用start()开始计时>>>t1.start()计时开始>>>t1提示;请输入stop()结束计时>>>t1总共运行5秒>>>t2 = MYtime()>>>t2.start()计时开始>>>t2.stop()计时结束>>>t2一共运行6秒>>>t1 + t2总共运行11秒

你需要使用time模块里的localtime方法获取时间

time.localtime返回struct_time的时间格式

表现你的类__str__()和__repr__()魔法方法

>>> import time>>> time.time<built-in function time>>>> time.time()1560518311.610051>>>

localtime方法获取时间

time.localtime

>>> import time>>> time.localtime()time.struct_time(tm_year=2019, tm_mon=6, tm_mday=14, tm_hour=21, tm_min=38, tm_sec=35, tm_wday=4, tm_yday=165, tm_isdst=0)>>>

源代码

    def stop(self):        self.stop = t.localtime()        print("计时结束") #考虑怎么进行计算localtime()返回一个时间元组的结构,只取前面6个元素,然后将stop的元素#依次减去start对应的元素,将差值存放在一个新的列表里
import time as tclass Mytime:    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 = Mytime()>>> t1.start()开始计时>>> t1.stop()总共运行了000005计时结束>>> 

基本实现了计时功能,接下下来需要完成print(t1)与t1均显示结果,那就要重写,str__()与__repr__()魔法方法来实现。

import time as tclass Mytime:    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 = Mytime()>>> t1.start()开始计时>>> t1.stop()总共运行了000008计时结束>>> t1总共运行了000008>>> 

似乎很不错,但是一位安全工作者,怎么能把自己的用户当成“朋友”呢?

>>> t1 = Mytime()>>> t1Traceback (most recent call last):  File "<pyshell#43>", line 1, in <module>    t1  File "C:\Python34\lib\idlelib\rpc.py", line 614, in displayhook    text = repr(value)  File "C:/Users/Administrator/Desktop/fugai.py", line 19, in __str__    return self.promptAttributeError: 'Mytime' object has no attribute 'prompt'>>> 

没有执行stop()那么_calc就是个摆设,要是先定义,不让在调用某个函数在进行其变量,就不会出错

import time as tclass Mytime:    def __init__(self):        self.prompt = "未开始计时"        self.lasted = []        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 = Mytime()>>> t1未开始计时>>> t1.start()Traceback (most recent call last):  File "<pyshell#46>", line 1, in <module>    t1.start()TypeError: 'int' object is not callable>>> 

怎么又报错了,书上是故意的,但是我是很不愿意报错,因为会浪费时间

这里简要说明

TypeError: 'int' object is not callable

大家要学会看异常,在调用t1.start()

Python认为他是个整型,这是因为如果类中的方法名(函数)和属性(变量)重名方法会覆盖属性

更改其所有self.start和self.end成self.begin和relf.start即可

但是不人性化

稍微加工一下

#记载时间模块import time as t 
class Mytimer :    def __init__ (self) :        self.unit = ['年','月','天','时','分','秒']        self.prompt = '未开始计时'        self.lasted = []        self.begin = 0        self.end = 0 
    #输入对象直接输出    def __str__ (self) :        return self.prompt
    def __repr__ (self) :        return self.prompt
    #开始计时模块    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._cacul()            print ('计时结束!')        #内部计算运行时间    def _cacul(self) :        self.prompt = '总共运行了'        self.lasted = []        for index in range (6) :            self.lasted.append(self.end[index] - self.begin[index])        self._judge1()        for index in range (6) :            if self.lasted[index] :                    self.prompt += (str(self.lasted[index]) + str(self.unit[index]))        #为下一轮计数初始化变量        self.begin = 0        self.end = 0
    #计算两个时间累计和    def __add__ (self,other) :        self.prompt = '两次总共运行了'        self.result = []        for index in range (6) :            self.result.append(self.lasted[index] + other.lasted[index])        self._judge2()        for index in range (6) :            if self.result [index] :                    self.prompt += str( self.result[index] ) + self.unit[index]         return self.prompt
    #判断两个数据是否出现负数    def _judge1(self) :        for index in range (6) :            if self.lasted[ index ] < 0 :                #当负数出现时,前一位-1                self.lasted [ index-1 ] -= 1                #当负数出现在分秒时,+60                if index == 5 or index == 4:                    """self.lasted [ index -1 ] -= 1"""                    self.lasted [ index ] += 60                #当负数出现在时时,+24                elif index == 3 :                    """self.lasted [ index-1 ] -= 1"""                    self.lasted [ index ] += 24                #当负数出现在天时,+31                elif index == 2 :                    """self.lasted [ index-1 ] -= 1"""                    self.lasted [ index ] +=31                #当负数出现在月时,+12                elif index == 1 :                    """self.lasted [ index-1 ] -= 1"""                    self.lasted [ index ] += 12
    #判断两个数据是或否可以进位    def  _judge2 (self) :        for index in range (5 , -1 , -1) :            if index == 5 or index == 4 :                if self.result [ index ] >= 60 :                    self.result [ index - 1 ] += 1                    self.result [ index ] -= 60            elif index == 3 :                if self.result [ index ] >= 24 :                    self.result [ index - 1 ] += 1                    self.result [ index ] -= 24            elif index == 2 :                if self.result [ index ] >= 31 :                    self.result [ index - 1 ] += 1                    self.result [ index ] -= 31            elif index == 1 :                if self.result [ index ] >= 12 :                    self.result [ index - 1 ] += 1                    self.result [ index ] -= 12            else :                pass 

运行后

>>> t1 = Mytimer()>>> print(t1)未开始计时>>> t1.start()计时开始...>>> t1.stop<bound method Mytimer.stop of 请先调用stop()停止计时!>>>> t1.stop()计时结束!>>> t1总共运行了20秒>>> 

原文发布于微信公众号 - 渗透云笔记(shentouyun)

原文发表时间:2019-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券