装饰器之技术小总结
作者:互联网
装饰器的作用是在已有的可调对象(callable object)的基础上,插入代码,以增强或者管理可调对象,装饰器的核心就是通过传入一个可调对象,然后返回一个可调对象,就其装饰的对象而言,可以分为函数装饰器和类装饰器,就其构造方法而言,可以用嵌套函数(nested functions)或者类方法。
下面通过几个小栗子总结装饰器的技术要点:
(1)@decorator的含义及其等效手动操作
@decorator实际上是自动的完成了将被装饰对象的接口传入装饰器,并返回一个可调对象。
>>> def decorator1(F): def wrapper(*args): print('i am in wrapper') F() print('it is doing @ operation....') return wrapper
>>> @decorator1 def F(): print('that is F() function') it is doing @ operation.... >>>
实际上,@操作的等效手动操作为:
>>> F=decorator1(F) it is doing @ operation....
所以我们可以通过这种手动等效操作来理解装饰器的设计结构:当出现@decoration时,把下面被装饰的接口作为参数传入decoration中,并形成一个可调对象,所以decoration的参数为F(不一定非与被装饰的接口的名字一样),然后返回wrapper可调对象。而当对F调用时,实际调用的是decorator1(F),即F()实际上是decorator1(F)(),即wrapper(*args).
调用F()
>>> F() i am in wrapper that is F() function
(2)基于类方法的装饰器
上栗中实际上是基于嵌套函数的装饰器,不再赘述,再总结下基于类的装饰器。类方法构造装饰器也要满足装饰器的基本功能:接收可调对象接口,返回可调对象。如果是类方法的话,对于这个要求,接受可调对象接口可以由__init__完成,返回可调对象,则应在类里定义__call__方法。下面用基于类方法来构造(1)中的构造器。
>>> class decorator1: def __init__(self,F): self.F=F print('it is doing @ operation...') def __call__(self,*args): print('i am in wrapper') self.F(*args) >>> @decorator1 def F(): print('that is F() function') it is doing @ operation...
调用F()
>>> F() i am in wrapper that is F() function
(3)多重装饰器
实际中,有可能对一个函数进行多重装饰,多重装饰的语法即直接在被装饰对象上面层层叠加@decoration。
>>> def dec1(F): def wrapper(*args): print('level 1') F() print('dec1') return wrapper >>> def dec2(F): def wrapper(*args): print('level 2') F() print('dec2') return wrapper >>> def dec3(F): def wrapper(*args): print('level 3') F() print('dec3') return wrapper >>> @dec1 @dec2 @dec3 def F(): print('F()') dec3 dec2 dec1 >>> F() level 1 level 2 level 3 F()
>>> def A(): print('A()') >>> A=dec1(dec2(dec3(A))) dec3 dec2 dec1 >>> A() level 1 level 2 level 3 A()
上面的例子给出了多重装饰器的等效手动方法,以及多重装饰器在传入被装饰对象接口参数的顺序(多重装饰器从下往上,手动方法的由内而外),调用被装饰对象时wrapper函数的调用顺序(多重装饰器从上往下,手动方法的由外而内)
标签:总结,level,可调,技术,wrapper,print,装饰,def 来源: https://www.cnblogs.com/johnyang/p/10494413.html