Как я могу упаковать несколько декораторов в один?

У меня есть несколько декораторов для каждой функции, есть ли способ упаковать их в один вместо?

@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)))