2018-07-18

                                Python装饰器

        装饰,顾名思义,是用来打扮什么东西的。Python装饰器是用来给某个函数或者模块添加功能的。为什么不直接修改模块呢,有的模块因为应用时间长或者代码复杂等各种原因,不便于直接修改,故使用装饰器对其添加功能,而且不改变调用方式。

1.在不修改原函数的条件下增加功能: 

        我们先建立一个函数:

        现在此函数不能修改,但是要加入测量运行时间的功能,我们再定义一个函数:

        在runtime函数中,可以使用runtime(add, a, b)调用add()函数,并传入a,b参数为add()函数增加测量运行时间功能。原来运行add(1,2),现在改为运行runtime(add, a, b)

        那么问题来了,原来习惯于使用add函数的人,现在要改变为使用runtime,一个函数还好,如果我要给100个函数增加功能,岂不是要重新记住100个新函数。

2.装饰器的基本使用:

        那有没有可能直接调用add函数就能完成加和与计时的功能呢,能不能直接让add=runtime呢,这里有两个问题,一个是参数数量不同,即使能用也和原来不一样;另一个问题更严重,直接改了add的内存地址,并未运行runtime,等下次使用add()的时候无法再调用以前的add()。

        如果使用add=runtime(add, a, b)则使用add会报a,b未定义的错误。

        所以还是要想办法使add=runtime,同时使其能载入参数。这里使用到嵌套函数。

        这样使add对应inner内存地址,inner和add参数一致,就能保证新add函数和旧add函数参数一致,同时在runtime中调用add,inner运行前旧add内容就加载到runtime中,故调用新add时,能够调用到旧add内容。这里需要说明的是,add=runtime(add)可以用在定义add函数前使用@runtime,即起到add = runtime(add)的作用。

3.三层装饰器的使用:

        对多个函数使用相同的修改,使用装饰器很方便,只需要定义一个装饰器即可。有的时候对多个函数修改并不完全一样,有细微差别,多写一个装饰器又麻烦,这时候就需要给层装饰器再加一层函数,达到增加参数的目的。

        如,给这个runtime函数增加一个打印‘hello’的功能,但是要控制不是每个使用装饰器的函数都打印‘hello’。

        此处,@prt('t')相当于add=prt('t')(add)

你可能感兴趣的:(2018-07-18)