python装饰器

Posted pfeiliu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python装饰器相关的知识,希望对你有一定的参考价值。

什么是装饰器,简单点来说,就是在不改变函数本身的前提下给一个函数添加新的功能。

def deco(fn):
    def wrapper(x):
        print(装饰器start-----------)
        fn(x)
        print("fn.__name__============",fn.__name__)
        print(装饰器start-----------)
    return wrapper

def log(params):
    print("params is..........",params)

deco(log)(我是被装饰函数)

如果把log函数作为参数传给deco函数,运行结果如下

装饰器start-----------
params is.......... 我是被装饰函数
fn.__name__============ log
装饰器start-----------

如果利用函数装饰器,在def log上加上@deco,然后直接调用log函数,结果也是一样的

def deco(fn):
    def wrapper(x):
        print(装饰器start-----------)
        fn(x)
        print("fn.__name__============",fn.__name__)
        print(装饰器start-----------)
    return wrapper
@deco
def log(params):
    print("params is..........",params)

log(我是被装饰函数)

result:

装饰器start-----------
params is.......... 我是被装饰函数
fn.__name__============ log
装饰器start-----------

看吧,一样的结果,只不过这次直接调用log函数,就可以实现新的功能,且没有改变他原有的代码!

 

带参数的装饰器

装饰器允许传入参数,一个携带了参数的装饰器将有三层函数,如下所示:

def log_with_param(text):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(call %s(): % func.__name__)
            print(args = {}.format(*args))
            print(log_param = {}.format(text))
            return func(*args, **kwargs)
        return wrapper
    return decorator

@log_with_param("param")
def test_with_param(p):
    print(test_with_param.__name__)

test_with_param("被装饰函数")

看到这个代码是不是又有些疑问,内层的decorator函数的参数func是怎么传进去的?和上面一般的装饰器不大一样啊。

其实道理是一样的,将其@语法去除,恢复函数调用的形式一看就明白了:

# 传入装饰器的参数,并接收返回的decorator函数
decorator = log_with_param("param")
# 传入test_with_param函数
wrapper = decorator(test_with_param)
# 调用装饰器函数
wrapper("I‘m a param")

输出结果与正常使用装饰器相同:

call test_with_param():
args = 被装饰函数
log_param = param
wrapper

至此,装饰器这个有点费解的特性也没什么神秘了。

以上是关于python装饰器的主要内容,如果未能解决你的问题,请参考以下文章

[TimLinux] Python 装饰器

python装饰器

python装饰器关键代码

Python装饰器

python之装饰器

python 装饰器