Python-装饰器应用程序的正确顺序
我正在装饰这样一个函数:Python-装饰器应用程序的正确顺序,python,decorator,Python,Decorator,我正在装饰这样一个函数: def some_abstract_decorator(func): @another_lower_level_decorator def wrapper(*args, **kwargs): # ... details omitted return func(*args, **kwargs) return wrapper 这正是您所期望的(应用一个低级修饰符,然后执行更多操作。我的问题是,我现在想使用functo
def some_abstract_decorator(func):
@another_lower_level_decorator
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
这正是您所期望的(应用一个低级修饰符,然后执行更多操作。我的问题是,我现在想使用functools.wrapps
,但我不知道该放在哪里。这是我的猜测,但我不知道是否会产生意外后果
def some_abstract_decorator(func):
@wraps(func)
@another_lower_level_decorator
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
(我当然在
另一个较低级别的修饰符中应用包装
)是的,我看对了。@另一个较低级别的修饰符
将返回一个函数,@wrapps
将进行包装,使其与func
同名。其工作方式如下
- 定义了
wrapper
。它使用参数调用func
调用另一个较低级别的修饰符
,其参数为包装器
。它返回的函数成为包装器
的新值
- 调用
wrapps(func)
创建一个包装器,将func的名称/docstring/等应用于调用它的任何函数
wrapps(func)
的返回值,即生成的包装函数,被传递给wrapper
的当前值。记住,这是另一个较低级别的装饰器的返回值
wrapps(func)(wrapper)
成为wrapper
的新值
- 该值由某个装饰器返回,使该函数适合用作装饰器
或者说实际上就是这样。我认为在实践中,包装器
只被重新分配一次。试试看:
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
正如您所看到的,它是有效的!docstring在那里,并且指定了名称
但这是一样的:
def some_abstract_decorator(func):
@another_lower_level_decorator
@wraps(func)
def wrapper(*args, **kwargs):
# ... details omitted
return func(*args, **kwargs)
return wrapper
wrapps
只修复docstring/名称。只要所有装饰程序都使用wrapps
,应用它的顺序就不重要了
顺便说一句,有:
谢谢。我认为你的第一个方法是正确的,在阅读了这篇文章之后。我意识到如果我在应用内部装饰器后使用@wrapps(func)
,我假设内部装饰器也使用wrapps(func)
。通过将其应用于修饰的包装器
函数,我只是将包装器
功能应用于我的结果函数,从而使事情更加明确(低级装饰器可能来自第三方,等等)。
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