python装饰器

python 装饰器详解
1、闭包
要想了解装饰器,首先要了解一个概念,闭包。什么是闭包,一句话说就是,
在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。
光说没有概念,直接上一个例子。

def outer(x):
    def inner(y):
        return x + y
    return inner

print(outer(6)(5))
-----------------------------
>>>11
如代码所示,在outer函数内,又定义了一个inner函数,并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了。
在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,
其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 52、装饰器
接下来就讲装饰器,其实装饰器就是一个闭包,装饰器是闭包的一种应用。
什么是装饰器呢,简言之,python装饰器就是用于拓展原来函数功能的一种函数,
这个函数的特殊之处在于它的返回值也是一个函数,
使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。

def debug(func):
    def wrapper():
        print("[DEBUG]: enter {}()".format(func.__name__))
        return func()
    return wrapper

@debug
def hello():
    print("hello")

hello()
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello
例子中的装饰器给函数加上一个进入函数的debug模式,
不用修改原函数代码就完成了这个功能,可以说是很方便了。

3、带参数的装饰器
上面例子中的装饰器是不是功能太简单了,那么装饰器可以加一些参数吗,
当然是可以的,另外装饰的函数当然也是可以传参数的。

def logging(level):
    def outwrapper(func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return outwrapper

@logging(level="INFO")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[INFO]: enter hello()
>>>hello, good morning
如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,
当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,
例子中传入了三个参数。

4、类装饰器
装饰器也不一定只能用函数来写,也可以使用类装饰器,
用法与函数装饰器并没有太大区别,
实质是使用了类方法中的call魔法方法来实现类的直接调用。

class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("[DEBUG]: enter {}()".format(self.func.__name__))
        return self.func(*args, **kwargs)

@logging
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello, good morning
类装饰器也是可以带参数的,如下实现

class logging(object):
    def __init__(self, level):
        self.level = level

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(self.level, func.__name__))
            return func(*args, **kwargs)
        return wrapper

@logging(level="TEST")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[TEST]: enter hello()
>>>hello, good morning
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值