12-装饰器

用于装饰函数

什么是装饰器,从表面上看,装饰器,那就得有装饰物和被装饰物吧,有了装饰物,就可以把被装饰物变得更漂亮些、功能更多些……

没错,在python中装饰器就扮演着装饰物的角色,那么问题来了,被装饰物是什么?实际上,我们需要另外重新定义一个新的函数(就是一个普通的函数),然后它就可以作为被装饰物了,当它被装饰器装饰过后,我们就称它为 被装饰函数

装饰器如何装饰被装饰函数,可以用一个 @ 符号来将两者联系起来。@是什么意思,就当做跟 qq一样就行了,在qq群发消息不是有 @某人吗,这样就可以跟对方建立联系了;在python就理解为 @装饰器 就行了。

例如:

#装饰器
def aaa(fun):                   #定义装饰器,名为aaa
    def bbb(*args, **kwargs):   #定义包装器函数bbb,用来修饰被装饰函数
        print('开始运行')
        fun(*args, **kwargs)
        print('运行结束')
    return bbb

@aaa
def xxx(str1='xxx'):               #定义被装饰函数xxx
    print('I am {}'.format(str1))

@aaa
def yyy(str2='yyy'):                #定义被装饰函数yyy
    print('I am {}'.format(str2))

调用一下:

>>>xxx()
开始运行
I am xxx
运行结束
------------------------------------
>>>yyy()
开始运行
I am yyy
运行结束

可以看到,只是调用了xxx函数,它就打印了属于aaa函数的东西,也就是说,xxx函数被aaa装饰了,它的功能更丰富了。

再来看一下这个装饰器函数:

#装饰器
def aaa(fun):                   #定义装饰器,名为aaa
    def bbb(*args, **kwargs):   #定义包装器函数bbb,用来修饰被装饰函数
        print('开始运行')
        fun(*args, **kwargs)
        print('运行结束')
    return bbb

装饰器名为aaa,携带了一个参数 fun,与一些普通函数的参数不同的是,装饰器函数携带的参数也是一个函数,也就是说在调用时传入了一个函数作为参数。

然后在装饰器内部还有一个函数 bbb,而且携带了参数 *args, **kwargs,之前在函数篇讲过了,带一个星号的参数 *args 表示可以接收多个传入的数据,函数会将这多个数据作为元组处理;而带两个星号的参数**kwargs表示可接收多个 默认参数,函数会将这多个默认参数作为字典处理。然而我们在定义装饰器时,并不知道被装饰函数需要几个参数,所以通过这样做,不论被装饰函数需要传入多少个参数都可以了。

最后装饰器返回的是内部包装函数bbb。

装饰器也可以带参数

只需要把装饰器理解成函数就可以了,函数可以带参数,所以装饰器也应该可以带参数

def sss(action):
    def aaa(fun):
        def bbb(*args, **kwargs):
            if action:
                print('用了aaa装饰器')
                fun(*args, **kwargs)
                print('用完aaa装饰器')   
            else:
                print('没有进行装饰')
        return bbb
    return aaa

@sss(1)
def xxx(str1='xxx'):
    print('I am {}'.format(str1))

@sss(0)
def yyy(a, b, c):
    print('I am ',a,b,c,sep=' ')

调用:

>>>xxx(111)
用了aaa装饰器
I am 111
用完aaa装饰器
>>>yyy(1,2,3)
没有进行装饰
posted @ 2020-07-27 14:18  aJream  阅读(20)  评论(0编辑  收藏  举报