博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Python】解析Python中的装饰器
阅读量:5013 次
发布时间:2019-06-12

本文共 1788 字,大约阅读时间需要 5 分钟。

python中的函数也是对象,函数可以被当作变量传递。

装饰器在python中功能非常强大,装饰器允许对原有函数行为进行扩展,而不用硬编码的方式,它提供了一种面向切面的访问方式。

 

装饰器

一个普通的装饰器一般是这样:

import functoolsdef log(func):    @functools.wraps(func)    def wrapper(*args, **kwargs):        print('call %s():' % func.__name__)        print('args = {}'.format(*args))        return func(*args, **kwargs)    return wrapper

这样就定义了一个打印出方法名及其参数的装饰器。

调用之:

@logdef test(p):    print(test.__name__ + " param: " + p)test("I'm a param")

输出:

call test():args = I'm a paramtest param: I'm a param

装饰器在使用时,用了@语法,让人有些困扰。其实,装饰器只是个方法,与下面的调用方式没有区别:

def test(p):    print(test.__name__ + " param: " + p)wrapper = log(test)wrapper("I'm a param")

@语法只是将函数传入装饰器函数,并无神奇之处。

值得注意的是@functools.wraps(func),这是python提供的装饰器。它能把原函数的元信息拷贝到装饰器里面的 func 函数中。函数的元信息包括docstring、name、参数列表等等。可以尝试去除@functools.wraps(func),你会发现test.__name__的输出变成了wrapper。

 

带参数的装饰器

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

import functoolsdef log_with_param(text):    def decorator(func):        @functools.wraps(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__)

看到这个代码是不是又有些疑问,内层的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 = I'm a paramlog_param = paramtest_with_param

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

装饰器这一语法体现了Python中函数是第一公民,函数是对象、是变量,可以作为参数、可以是返回值,非常的灵活与强大。

原文链接:

转载于:https://www.cnblogs.com/HDK2016/p/10973193.html

你可能感兴趣的文章
Apache2.4使用require指令进行访问控制
查看>>
冗余关系_并查集
查看>>
做最好的自己(Be Your Personal Best)
查看>>
如何搭建github+hexo博客-转
查看>>
HW2.2
查看>>
将Windows Server 2016 打造成工作站(20161030更新)
查看>>
5大主浏览器css3和html5兼容性大比拼
查看>>
hdu-5894 hannnnah_j’s Biological Test(组合数学)
查看>>
scss常规用法
查看>>
css定位position属性深究
查看>>
android中不同版本兼容包的区别
查看>>
Static 与 new 的问题【待解决】
查看>>
xml
查看>>
在 mvc4 WebApi 中 json 的 跨域访问
查看>>
敏捷开发文章读后感
查看>>
xposed获取context 的方法
查看>>
html5 canvas 图像处理
查看>>
He who hesitates is Lost
查看>>
php中引用&的真正理解-变量引用、函数引用、对象引用
查看>>
关于<form> autocomplete 属性
查看>>