Ответ 1
Я бы сказал, что вы не должны - использование оригинальных имен для декораторов дает гораздо лучшую читаемость.
Однако, если вы действительно этого хотите, вы можете сделать это следующим образом:
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) # Not required, but generally considered good practice
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):
# Please note that for the exact same result as in the other one,
# the order of decorators has to be reversed compared to normal decorating
newfunc = decorator1(name=name, state=state)(func)
newfunc = decorator2(foo=foo, bar=bar)(newfunc)
# Note that functools.wraps shouldn't be required anymore, as the other decorators should do that themselves
return newfunc
return inner
Для некоторых это может выглядеть проще. Тем не менее, люди, имеющие опыт работы с Python, используются для декораторов, применяемых с помощью @- и даже по этой причине мне нравится мой первый вариант. Я знаю, что я бы взял три раза, чтобы прочитать этот код в первый раз и понять, что он делает.
Это просто на самом деле - просто напишите декоратор, который возвращает еще один декоратор, который будет иметь внутреннюю функцию, украшенную двумя другими декораторами;)
Также может быть хорошей идеей использовать functools.wraps, ради хороших привычек. Это стандартная библиотека и много помогает при использовании отладки и интерактивной консоли: https://docs.python.org/3.7/library/functools.html
В общем, я бы сказал, что одна дополнительная строка кода более чем заслуживает ясности использования декораторов отдельно. Вы будете благодарить себя, когда прочитаете свой собственный код еще через три месяца.