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
添加回答
举报