python 理解functools.wraps
来源:互联网 发布:mac 鼠标右键 编辑:程序博客网 时间:2024/05/16 06:18
先复习下装饰器
# coding=utf-8def logged(func): def with_logging(*args, **kwargs): """ 哈哈哈,这里是with_logging :param args: :param kwargs: :return: """ print func.__name__, " was called..." return func(*args, **kwargs) return with_logging@loggeddef f(x): """ 哈哈,这是f :param x: :return: """ return x + x * xprint f.__name__print f.__doc__
打印结果是:
(venv) ➜ myApp git:(v1.6_dev) ✗ python 1.pywith_logging 哈哈哈,这里是with_logging :param args: :param kwargs: :return:
理论上这是不对的,因为函数f的信息已经获取不到了。。都被with_logging取代了。
解决方案:
# coding=utf-8import functoolsdef logged(func): @functools.wraps(func) def with_logging(*args, **kwargs): """ 哈哈哈,这里是with_logging :param args: :param kwargs: :return: """ print func.__name__, " was called..." return func(*args, **kwargs) return with_logging@loggeddef f(x): """ 哈哈,这是f :param x: :return: """ return x + x * xprint f.__name__print f.__doc__
打印结果是:
(venv) ➜ myApp git:(v1.6_dev) ✗ python 1.pyf 哈哈,这是f :param x: :return:
以上是别的教程写的解决方案,突然对这个functools.wraps()有点兴趣,它到底是如何做到的呢?
functools.warp方法就是把被wrapped的函数的属性传递给wrapper的函数。
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')WRAPPER_UPDATES = ('__dict__',)def update_wrapper(wrapper, wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): """Update a wrapper function to look like the wrapped function wrapper is the function to be updated wrapped is the original function assigned is a tuple naming the attributes assigned directly from the wrapped function to the wrapper function (defaults to functools.WRAPPER_ASSIGNMENTS) updated is a tuple naming the attributes of the wrapper that are updated with the corresponding attribute from the wrapped function (defaults to functools.WRAPPER_UPDATES) """ for attr in assigned: setattr(wrapper, attr, getattr(wrapped, attr)) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr, {})) # Return the wrapper so this can be used as a decorator via partial() return wrapperdef wraps(wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): """Decorator factory to apply update_wrapper() to a wrapper function Returns a decorator that invokes update_wrapper() with the decorated function as the wrapper argument and the arguments to wraps() as the remaining arguments. Default arguments are as for update_wrapper(). This is a convenience function to simplify applying partial() to update_wrapper(). """ return partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
这个乍一看不是很理解,这个怎么和普通的装饰器不大一样呀。普通的长得像:
def out_wrapper(func): def in_wrapper(*args, **kwargs): print ‘in_wrapper’ return func(*args, **kwargs) return in_wrapper
不过剥丝抽茧,先去除注释:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')WRAPPER_UPDATES = ('__dict__',)def update_wrapper(wrapper, wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): for attr in assigned: setattr(wrapper, attr, getattr(wrapped, attr)) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr, {})) return wrapperdef wraps(wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): return partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
嗯,看起来简单清爽多了。考虑到偏函数,上面代码可以转成:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')WRAPPER_UPDATES = ('__dict__',)def update_wrapper(wrapper, wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): for attr in assigned: setattr(wrapper, attr, getattr(wrapped, attr)) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr, {})) return wrapperdef wraps(wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): def in_wrapper(wrapper, wrapped=wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): return update_wrapper(wrapper, wrapped=wrapped, assigned = WRAPPER_ASSIGNMENTS,updated = WRAPPER_UPDATES) return in_wrapper
一般带参数的装饰器,是三层的,类似:
def wrapper(x): def out_wrapper(func): def in_wrapper(*args, **kwargs): print ‘in_wrapper’ return func(*args, **kwargs) return in_wrapper return out_wrapper
虽然长得不一样,但思路就是返回一个能包装函数的函数变量,这帮作者写代码真是骚。
end...
阅读全文
0 0
- python 理解functools.wraps
- functools.wraps
- functools.wraps
- functools.wraps
- 用Python functools.wraps实现装饰器
- 用Python functools.wraps实现装饰器
- Python 装饰器之 functools.wraps
- python中functools.wraps的作用
- Python 入门:装饰器(decorator)、@functools.wraps、@staticmethod、@classmethod
- What does functools.wraps do?
- What does functools.wraps do?
- What does functools.wraps do?
- python 学习笔记——python 装饰器(三) @functools.wraps(0
- Python 中实现装饰器时使用 @functools.wraps 的理由
- 使用functools.wraps完善装饰器
- python functools
- python functools
- python functools
- 环境变量的配置--java开发环境
- 【Android资源管理和打包】深入理解Gradle
- 阿里云四轮技术面回顾(四面跪归)
- MTK Android Driver :battery
- 写给 Android 开发者的混淆使用手册
- python 理解functools.wraps
- Python中函数的参数定义和可变参数
- Android 异步查询框架AsyncQueryHandler分析
- BITSET用法详解
- JNDI到底是什么?
- 神经网络浅讲:从神经元到深度学习
- 大数据开源处理工具汇总
- android界面:上下固定且中间内容滚动的页面制作
- caffe 学习汇总