2010-09-22 43 views
3

是否可以根據條件來修飾功能?有條件地裝飾Python3嗎?

網HRS歐洲:

if she.weight() == duck.weight(): 
    @burn 
def witch(): 
    pass 

我只是想知道,如果可以使用邏輯(當witch是叫什麼名字?)要弄清楚是否要裝飾witch@burn

如果沒有,是否有可能在裝飾器中創建一個條件來達到相同的效果? (witch被稱爲undecorated。)

我很感謝任何幫助解決這一點。

回答

3

有可能通過重新分配enable/disable decorators

def unchanged(func): 
    "This decorator doesn't add any behavior" 
    return func 

def disabled(func): 
    "This decorator disables the provided function, and does nothing" 
    def empty_func(*args,**kargs): 
     pass 
    return empty_func 

# define this as equivalent to unchanged, for nice symmetry with disabled 
enabled = unchanged 

# 
# Sample use 
# 

GLOBAL_ENABLE_FLAG = True 

state = enabled if GLOBAL_ENABLE_FLAG else disabled 
@state 
def special_function_foo(): 
    print "function was enabled" 
9

您可以創建一個 '有條件' 裝飾:

>>> def conditionally(dec, cond): 
    def resdec(f): 
     if not cond: 
      return f 
     return dec(f) 
    return resdec 

用法示例如下:

>>> def burn(f): 
    def blah(*args, **kwargs): 
     print 'hah' 
     return f(*args, **kwargs) 
    return blah 

>>> @conditionally(burn, True) 
def witch(): pass 
>>> witch() 
hah 

>>> @conditionally(burn, False) 
def witch(): pass 
>>> witch() 
+1

+1我喜歡比我解決這個更多,因爲它保持與裝飾主題,看起來很乾淨,海事組織。 – nilamo 2010-10-25 16:21:05

+0

這是一個古老的答案,但沒有人知道如何使用此模式將參數傳遞給有條件包裝的裝飾器? – 2017-11-01 14:37:39

4

裝飾是重新定義的函數只是語法糖,例如:

def wrapper(f): 
    def inner(f, *args): 
     return f(*args) 
    return lambda *args: inner(f, *args) 

def foo(): 
    return 4 
foo = wrapper(foo) 

這意味着你可以做舊的方式,之前的語法糖存在:

def foo(): 
    return 4 
if [some_condition]: 
    foo = wrapper(foo)