将一个装饰器列表应用于可调用的?

时间:2010-11-08 10:03:04

标签: python decorator

给定一个装饰器方法列表,如何将它们应用于可调用方法?

例如,因为:

@foo
@bar
def baz():
    pass

...与:

相同
def baz():
    pass
baz = foo(bar(baz)))

...人们会认为,通过装饰者列表([foo, bar]),它们可以动态地应用于baz

2 个答案:

答案 0 :(得分:12)

还有另一位装饰师!

def yad(decorators):
    def decorator(f):
        for d in reversed(decorators):
            f = d(f)
        return f
    return decorator

示例用法

 list_of_decorators = [foo, bar]

@yad(list_of_decorators)
def foo():
    print 'foo'

没有装饰器语法,它看起来像

 func = yad(list_of_decorators)(func)

如果您想将相同的列表应用于多个功能,您可以这样做:

 dec = yad(list_of_decorators)

 func1 = dec(func1)

 @dec
 def func2():
     pass

正如评论中的递归指出一样,您可以定义yad(我确定有一个更好的名称)来接受*decorators而不是decorators。如果您正在创建 in situ 列表,则不必使用括号。如果列表是在其他地方创建的,我演示的方式会更好。

答案 1 :(得分:2)

有着经典的经典之作:

def compose(f, g):
    def composed(*a, **k):
        return g(f(*a, **k))
    return composed

@compose(foo, compose(bar, baz))
def blam():
    pass
相关问题