其他分享
首页 > 其他分享> > 装饰器之技术小总结

装饰器之技术小总结

作者:互联网

装饰器的作用是在已有的可调对象(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