我正在装饰一个函数:
def some_abstract_decorator(func):
@another_lower_level_decorator
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
这就是你所期望的(应用一个低级装饰器,然后做更多的东西。我的问题是我现在想要使用functools.wraps
而我不知道在哪里放它。这是我的猜测,但我不知道它是否会产生意想不到的后果。
def some_abstract_decorator(func):
@wraps(func)
@another_lower_level_decorator
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
(我当然也在wraps
内部应用another_lower_level_decorator
)
答案 0 :(得分:2)
没错。这种方式的工作方式是
wrapper
已定义。它使用其参数调用func
。another_lower_level_decorator
,其中wrapper
为其参数。它返回的函数成为wrapper
的新值。wraps(func)
来创建一个将应用名称/ docstring / etc的包装器。 func
对任何被调用的函数。wraps(func)
的返回值,即生成的包装函数,将传递当前值wrapper
。记住,这是another_lower_level_decorator
的返回值。wraps(func)(wrapper)
成为wrapper
。some_abstract_decorator
返回,使该函数适合用作装饰器。wrapper
只会被重新分配一次。
答案 1 :(得分:2)
尝试一下:
from functools import wraps
def another_lower_level_decorator(func):
@wraps( func )
def wrapped(*args, **kwargs):
return func(*args, **kwargs)
return wrapped
def some_abstract_decorator(func):
@wraps(func)
@another_lower_level_decorator
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
@some_abstract_decorator
def test():
""" This is a docstring that should be on the decorated function """
pass
help(test)
打印:
Help on function test in module __main__:
test(*args, **kwargs)
This is a docstring that should be on the decorated function
正如你所看到的那样有效!文档字符串在那里,并指定了名称。
但这也是一样的:
def some_abstract_decorator(func):
@another_lower_level_decorator
@wraps(func)
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
wraps
只修复了文档字符串/名称。只要所有装饰器都使用wraps
,您应用它的顺序无关紧要
顺便说一下,有a much cooler decorator library:
from decorator import decorator
@decorator
def another_decorator(func, *args, **kwargs):
return func(*args, **kwargs)
@decorator
@another_decorator
def some_abstract_decorator(func, *args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
@some_abstract_decorator
def test(x):
""" this is a docstring that should be on the decorated function """
pass
答案 2 :(得分:1)
是的,这对我来说是正确的。 @another_lower_level_decorator
将返回一个函数,@wraps
将换行,以便它与func
具有相同的名称。