2010-11-08 52 views
4

給定一個裝飾器方法列表,如何將這些應用於可調用方法?將一個裝飾器列表應用於可調用?

例如,因爲:

@foo 
@bar 
def baz(): 
    pass 

...是一樣的:

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

...一會認爲與裝飾的([foo, bar])的列表,他們可以應用動態地到baz

+0

「一將假設」?真?基於什麼?是什麼讓你得出這個結論? – 2010-11-08 12:17:29

+2

@ S.Lott因爲它是Python?我的一般假設是我可以做任何我想做的事情。 – aaronasterling 2010-11-08 12:31:39

+0

@aaronasterling,我想你會把Python和神祕的[DWIM](http://en.wikipedia.org/wiki/DWIM)計算機語言混淆起來。 – martineau 2010-11-08 20:00:26

回答

11

還有另一個裝修工!

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。然後,如果您正在創建名單,則不必使用括號。如果列表是在其他地方創建的,我演示的方式會更好。

+3

如果你用這個定義yad:'def yad(* decorators):',那麼你可以避免列表中的括號。 – recursive 2010-11-08 10:19:38

+0

@recursive這就是我原來的樣子,但後來我看到OP使用了方括號,並且可能在其他地方構建了列表(因此強調不使用裝飾器語法)。雖然好提。 – aaronasterling 2010-11-08 10:47:14

+0

謝謝,我用一個簡單的循環去了:'換成d(裝飾):baz = d(baz)' – 2010-11-17 15:52:46

2

隨着alltime經典:

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

@compose(foo, compose(bar, baz)) 
def blam(): 
    pass 
相關問題