如何将多个装饰器装入一个?

时间:2010-02-02 09:04:38

标签: python decorator

我在每个函数上都有几个装饰器,有没有办法将它们打包成一个呢?

@fun1
@fun2
@fun3
def do_stuf():
    pass

更改为:

@all_funs #runs fun1 fun2 and fun3, how should all_funs look like?
def do_stuf():
    pass

3 个答案:

答案 0 :(得分:10)

装饰者原则上只是语法糖:

def do_stuf():
    pass

do_stuf = fun1(do_stuf)

所以在你的all_fun中,你需要做的就是将函数包装在同一类装饰器中:

def all_funs(funky):
    return fun1(fun2(fun3(fun4(funky)))

如果您有装饰器的参数,事情会变得更复杂(但只有一点点)。

答案 1 :(得分:7)

也可以编写支持装饰器链接的通用装饰器:

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 :(得分:1)

def all_funs(f):
    return fun1(fun2(fun3(f)))