functools.wraps
来源:互联网 发布:nginx 只允许内网访问 编辑:程序博客网 时间:2024/06/04 23:26
目录(?)[+]
研究一下 functools.wraps
。
用法
def deco(f): # @wraps(f) def hello(*args, **kwargs): print(f.__name__) # print `test` return wrapper@decodef test(): return 1 + 1print(test.__name__) # print `hello`
在 hello
裡 print 出 'test',這個沒什麼問題,但是在宣告完後,如果想確認 test
的 __name__
attribute,會發現 print 出的是 'hello',這是因為 test
在被 decorate 後,其實已經變成 hello
,真正的 test
則被包在 hello
裡執行。如果把 @wraps
前的註解拿掉,就會發現最後 print 出來的會變回原來的 'test',因為wraps
這個 decorator 會將一些原本 function 的 attribute 複製到外面的 function 上,可以看一下內部實作。
實作
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 the wrapper so this can be used as a decorator via partial() return wrapperdef wraps(wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): return partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
首先先看 wraps
這個 function,參數中 wrapped
是參數傳進來的 function,assigned
是要複製的 attribute,updated
是要更新的 attribute, 這邊可以看到是直接呼叫 partial
,至於這個 function 的用法可以參考:
- python的functools.partial用法解释
- python 的 functools.partial 函數
簡單說就是像把 wrapped
, assigned
, updated
丟進 update_wrapper
的參數裡,並 return 一個新 function,接著只要把還沒填的參數丟進這個新的 function 就可以了。因為是 decorator 的用法,所以parital
產生的 function 在 return 時會被執行,接著跑到 update_wrapper
。
update_wrapper
這邊多了個 wrapper
參數,也就是被 @wraps
裝飾 的 function,以最上面的例子來看,就是 hello
function 。這邊可以順便注意一下傳進 decorator function 參數的順序,首先會先傳進來的是 decorator function 的參數(剛才的 wrapped
),再來是被 decorate 的 function 本身(wrapper
),再來則是被 decorate 的 function 的參數這樣(這邊沒有使用)。
接著 update_wrapper
會將 wrapped
裡的 __module__
, __name__
, __doc__
複製到 wrapper
上,並將__dict__
也更新過去,大致就完成了~~。
這邊好奇為啥 __dict__
也要複製過去,應該說 function 為啥要有 __dict__
,搜尋了一下,看到stackoverflow 上也有人問,在答案的連結裡可以看到一些用法:
def a(): passa.publish = 1a.unittest = '''...'''if a.publish: print a()if hasattr(a, 'unittest'): testframework.execute(a.unittest)
參考網址:
What does functools.wraps do?
Python: Why to use @wraps with decorators?
what is the difference between functools.wraps and update_wrapper
- functools.wraps
- functools.wraps
- functools.wraps
- python 理解functools.wraps
- What does functools.wraps do?
- What does functools.wraps do?
- What does functools.wraps do?
- 使用functools.wraps完善装饰器
- 用Python functools.wraps实现装饰器
- 用Python functools.wraps实现装饰器
- Python 装饰器之 functools.wraps
- python中functools.wraps的作用
- 探究functools模块wraps装饰器的用途
- 探究functools模块wraps装饰器的用途
- Python 入门:装饰器(decorator)、@functools.wraps、@staticmethod、@classmethod
- python 学习笔记——python 装饰器(三) @functools.wraps(0
- Python 中实现装饰器时使用 @functools.wraps 的理由
- functools
- 构造函数
- BOTTLE的高级技巧
- 自定义控件实战高级实用篇 ,仿淘宝商品浏览界面,图书阅读器平滑翻页,滚动选择器
- STL array的max_size方法(14)
- Python 扩展中的Py_BuildValue()函数
- functools.wraps
- gridview控件实现行变色
- POJ 1523 SPF (无向图求割点)
- What does functools.wraps do?
- 智能电视主界面设计演变及开发工具发展
- Codeforces Round #226 (Div. 2) D. Bear and Floodlight
- Web_PHP_DedeCMS_资讯网址;
- css样式表中的样式覆盖顺序
- JAVA学习第一课(初识JAVA)