文章目錄
- 一、子產品簡介
- 二、子產品函數
-
- 1. `functools.lru_cache(maxsize=128, typed=False)`
- 2. `functools.partial(func, /, *args, **keywords)`
- 3. `functools.update_wrapper`
- 4. `@functools.wraps`
-
- 4.1 裝飾器原型
- 4.2 裝飾器定義
- 4.3 裝飾器應用
- 三、參考資料
一、子產品簡介
The functools module is for higher-order functions: functions that act on or return other functions.
functools子產品用于高階函數,高階函數顧名思義也是一種函數,不同的是,高階函數可以作用于或者傳回其他函數。
二、子產品函數
1. functools.lru_cache(maxsize=128, typed=False)
functools.lru_cache(maxsize=128, typed=False)
2. functools.partial(func, /, *args, **keywords)
functools.partial(func, /, *args, **keywords)
3. functools.update_wrapper
functools.update_wrapper
4. @functools.wraps
@functools.wraps
這是一個裝飾器。
4.1 裝飾器原型
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
4.2 裝飾器定義
This is a convenience function for invoking update_wrapper() as a function decorator when defining a wrapper function.
在定義裝飾器函數内部的嵌套函數時,在嵌套函數上方使用@functools.wraps()相當于調用函數functools.update_wrapper()
It is equivalent to partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated).
這相當于partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
4.3 裝飾器應用
在Python裝飾器從初識到精通中,我們知道使用裝飾器可以為代碼編寫帶來很大的便利, 但是使用裝飾器時,也可能會影響到Python中的自省特性(特别在使用互動式Python shell時會用到該特性),這就可以通過使用@functools.wraps()裝飾器來解決。
- 自省的概念:
所謂自省是指,Python中對象可以在運作時知道其各類屬性。如:一個函數知道其自身名稱以及幫助文檔内容。
如:
In [1]: print
Out[1]: <function print>
In [2]: print.__name__
Out[2]: 'print'
In [3]: help(print)
- 自省的使用:
自省特性同樣适用于使用者自定義的函數,如:
In [5]: say_whee
Out[5]: <function __main__.say_whee>
In [6]: say_whee.__name__
Out[6]: 'say_whee'
- 當自省遇到裝飾器:
但問題是:當對自定義函數使用裝飾器後,将對say_whee()函數的自省特性産生影響,如:
def do_twice(func):
"""該裝飾器用于将被裝飾函數執行兩次"""
def wrapper(*args, **kwargs):
func(*args, **kwargs)
func(*args, **kwargs)
return wrapper
@do_twice
def say_whee():
"""這是一個簡單的被裝飾函數"""
print("Whee!")
say_whee()
print("執行print(say_whee)後的結果為:")
print(say_whee, end="\n" * 2)
print("執行print(say_whee.__name__)後的結果為:")
print(say_whee.__name__, end="\n" * 2)
print("執行print(help(say_whee))後的結果為:")
print(help(say_whee))
上述程式的執行結果為:
Whee!
Whee!
執行print(say_whee)後的結果為:
<function do_twice.<locals>.wrapper at 0x7fe48aa679d8>
執行print(say_whee.__name__)後的結果為:
wrapper
執行print(help(say_whee))後的結果為:
Help on function wrapper in module __main__:
wrapper(*args, **kwargs)
None
即:由于對函數say_whee使用了裝飾器do_twice的緣故,導緻其原本的屬性被遺失。
- 裝飾器産生的問題用裝飾器來解決:
使用@functools.wraps()裝飾器即可以解決此問題(用魔法來打敗魔法),如:
import functools
def do_twice(func):
"""該裝飾器用于将被裝飾函數執行兩次"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
func(*args, **kwargs)
return wrapper
@do_twice
def say_whee():
"""這是一個簡單的被裝飾函數"""
print("Whee!")
say_whee()
print("執行print(say_whee)後的結果為:")
print(say_whee, end="\n" * 2)
print("執行print(say_whee.__name__)後的結果為:")
print(say_whee.__name__, end="\n" * 2)
print("執行print(help(say_whee))後的結果為:")
print(help(say_whee))
上述代碼的執行結果為:
Whee!
Whee!
執行print(say_whee)後的結果為:
<function say_whee at 0x7f1360f8da60>
執行print(say_whee.name)後的結果為:
say_whee
執行print(help(say_whee))後的結果為:
Help on function say_whee in module main:
say_whee()
這是一個簡單的被裝飾函數
None
三、參考資料
- [1] Primer on Python Decorators