3 回答

TA貢獻1772條經驗 獲得超6個贊
它支持兩種開發風格:嵌套(如在 python 裝飾器工廠中)和平面(少一層嵌套)。這是您的示例在平面模式下的實現方式:
from decopatch import function_decorator, DECORATED
from makefun import wraps
@function_decorator
def logged(disabled=False, logger=logging.getLogger('default'), func=DECORATED):
# (1) create a signature-preserving wrapper
@wraps(func)
def _func_wrapper(*f_args, **f_kwargs):
# stuff
result = func(*f_args, **f_kwargs)
# stuff
return result
# (2) return it
return _func_wrapper
請注意,我使用makefun.wraps而不是functools.wraps此處,以便完全保留簽名(如果參數無效,則根本不會調用包裝器)。
decopatch支持另一種開發風格,我稱之為double-flat,專門用于創建這樣的簽名保留函數包裝器。您的示例將像這樣實現:
from decopatch import function_decorator, WRAPPED, F_ARGS, F_KWARGS
@function_decorator
def logged(disabled=False, logger=logging.getLogger('default'),
func=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS):
# this is directly the signature-preserving wrapper
# stuff
result = func(*f_args, **f_kwargs)
# stuff
return result
您可以檢查兩種樣式是否按預期工作:
@logged(disabled=True)
def foo():
pass
@logged
def bar():
pass
foo()
bar()
請查看文檔以獲取詳細信息。

TA貢獻1765條經驗 獲得超5個贊
或者使用部分(在 Python 食譜中找到的解決方案:9.6)
from functools import wraps, partial
def foo(func=None, *, a=None, b=None):
if func is None:
return partial(foo, a=a, b=b)
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
添加回答
舉報