我认为你不应该这样做——使用原始名称可以使修饰符更易读。但是,如果你真的想这样做,可以按照以下方式进行:
import functools
from moduleA import decorator1
from moduleB import decorator2
def my_decorator(foo, bar, name, state):
def inner(func):
@decorator2(foo=foo, bar=bar)
@decorator1(name=name, state=state)
@functools.wraps(func)
def newfunc(*args, **kwargs)
return func(*args, **kwargs)
return newfunc
return inner
@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
根据评论,这里提供一种替代方法:
def my_decorator(foo, bar, name, state):
def inner(func):
newfunc = decorator1(name=name, state=state)(func)
newfunc = decorator2(foo=foo, bar=bar)(newfunc)
return newfunc
return inner
对于一些人来说,这可能看起来更简单。但是,熟悉Python的人习惯于使用@应用装饰器——仅仅因为这个原因,我更喜欢第一个选项。我知道我需要花三倍的时间来第一次阅读并理解它所做的事情。
实际上很简单——只需编写一个返回另一个装饰器的装饰器,该装饰器将具有其内部函数由其他两个装饰器装饰的效果;)
为了养成良好的习惯,使用functools.wraps也是一个好主意。它是标准库,并且有助于调试和交互式控制台使用:
https://docs.python.org/3.7/library/functools.html
总的来说,我认为多出来的一行代码完全值得使用分开的装饰器带来的清晰度。当你在三个月后再次阅读自己的代码时,你会感激自己的。
@customdecorator
接收装饰器。但实际情况并非如此。 - Lin