装饰器

就是把自己定义的函数装饰一遍,在原来函数的基础上做些其他操作,然后返回一个新的函数,调用名称是一样的,只是内容稍有变化(注意是新的,已经不是本来定义的函数了,但是原来的函数最终还是会在装饰器最内层返回的,只是返回时添加了些东西,比如逻辑判断,打印,往哪个列表添加东西等等操作,比如在原来函数功能的基础上,判断是否登录,是否是VIp,再执行该函数)

装饰函数无参数

可以看出调用decorator函数,返回的是wrapper函数对象,而不是abc这个函数对象,
abc这个函数在wrapper中已经是被调用了的,只是返回一个结果。以上代码的运行结果如下图,可以看出装饰

#装饰函数无参数
def decorator(foo):
    def wrapper():
        print('wrapper')
        return foo()
    return wrapper

#自定义函数
def abc():
    print ('abc')

#装饰函数abc,使之函数abc()运行时,提前print('wrapper')
abc = decorator(abc)   #  abc = wrapper
abc()       #  wrapper      abc
print(abc())      #  wrapper      abc  None

python的装饰器语法就是自动调用decorator函数,并以自定义的函数abc函数对象为参数,返回wrapper函数对象,这样一个过程。
  切记 : 回调函数不可以使用装饰器,如果非要使用那就把这个回调函数名再赋值一个新名字,用新名字的函数去装饰

def decorator(foo):
    def wrapper():
        print ('@wrapper')
        return foo()
    return wrapper

@decorator # @相当于abc = decorator(abc),只是他在定义定义其他函数时就把那个函数装饰了,把函数名作为装饰器的参数
def abc():
    print ('abc')
abc()   #   @wrapper         abc
print(abc())      #   @wrapper   abc   None

带参数的装饰器:

接下来,再深一步来说说带参数的装饰器, 其实这个只比上面那个无参数装饰器多了一步,就是先调用装饰器函数,再返回真正的装饰器,之后的步骤和无参数的一样了,说得太抽象?
直接上代码,这样就明显了,先调用用最外层的函数,返回的是一个真正的装饰器,然后像之前无参数的时候一样,修饰abc函数后返回新的函数对象

def decoratorFunc(arg):
    def decorator(foo):
        def wrapper():
            if arg == 0:
                print('lalala')
            return foo()
        return wrapper
    return decorator

deco0 = decoratorFunc(0)     #   deco0 = decorator  带有暂时不用的参数0     return decorator
deco1 = decoratorFunc(1)     #   deco1 = decorator     带有暂时不用的参数1     return decorator
def abc():
    print('abc')
abc0 = deco0(abc)      #    abc0 = decorator(abc)   return wrapper
abc1 = deco1(abc)      #    abc1 = decorator(abc)   return wrapper
abc0()     #lalala    abc
abc1()      # abc

@decoratorFunc(0)
def abc():
     print ('abc')
abc1()      # abc

输出:
lalala
abc
abc
abc

写更普通的装饰器,如果被装饰的函数有参数怎么办?很简单,利用python的可变长度参数就行。
注意,是在wrapper这个函数上我们写上python的可变长度参数,而装饰器函数decorator的参数永远只有一个,就是函数对象。看以下代码,是无参数装饰器的例子,
如果是带参数的函数,也只需要把wrapper改成接收可变长度参数就行

def decorator(foo):
    def wrapper(*args, **kwargs):
        print ('wrapper')
        return foo(*args, **kwargs)
    return wrapper
@decorator
def abc(arg):
    print ('abc:', arg)

abc('你好啊')     #wrapper        abc: 你好啊
写入自己的博客中才能记得长久
原文地址:https://www.cnblogs.com/heris/p/11444613.html