Как я могу упаковать несколько декораторов в один?
У меня есть несколько декораторов для каждой функции, есть ли способ упаковать их в один вместо?
@fun1
@fun2
@fun3
def do_stuf():
pass
измените на:
@all_funs #runs fun1 fun2 and fun3, how should all_funs look like?
def do_stuf():
pass
Ответы
Ответ 1
Также можно написать общий декоратор, который поддерживает цепочку декораторов:
def fun1(f):
print "fun1"
return f
def fun2(f):
print "fun2"
return f
def fun3(f):
print "fun3"
return f
def chained(*dec_funs):
def _inner_chain(f):
for dec in reversed(dec_funs):
f = dec(f)
return f
return _inner_chain
@fun1
@fun2
@fun3
def do_stuff():
pass
@chained(fun1, fun2, fun3)
def do_stuff2():
pass
all_funs = chained(fun1, fun2, fun3)
@all_funs
def do_stuff3():
pass
Ответ 2
Декоратор в принципе предназначен только для синтаксического сахара:
def do_stuf():
pass
do_stuf = fun1(do_stuf)
Итак, в вашем all_fun все, что вам нужно сделать, - это обернуть функцию в одну и ту же цепочку декораторов:
def all_funs(funky):
return fun1(fun2(fun3(fun4(funky)))
Вещи получают немного (но только litte) более сложные, если у вас есть параметры для декораторов.
Ответ 3
def all_funs(f):
return fun1(fun2(fun3(f)))