Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a list of decorators to a callable?

Given a list of decorator methods, how would one apply those to a callable?

For example, since:

@foo
@bar
def baz():
    pass

...is the same as:

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

...one would assume that with a list of decorators ([foo, bar]) they could be applied to baz dynamically.

like image 501
Phillip B Oldham Avatar asked Nov 08 '10 10:11

Phillip B Oldham


1 Answers

With yet another decorator!

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

example usage

 list_of_decorators = [foo, bar]

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

Without the decorator syntax, it would look like

 func = yad(list_of_decorators)(func)

If you wanted to apply the same list to multiple functions, you can do it like:

 dec = yad(list_of_decorators)

 func1 = dec(func1)

 @dec
 def func2():
     pass

As recursive points out in the comments, you can define yad (I'm sure there's a better name for this) to accept *decorators instead of decorators. Then you don't have to use brackets if you're creating the list in situ. The way that I've demonstrated is better if the list is created elsewhere.

like image 101
aaronasterling Avatar answered Sep 18 '22 13:09

aaronasterling