2016-02-23 41 views
34

當使用相同的裝飾器有或沒​​有括號時有什麼區別Python?例如:使用python裝飾器有無括號

沒有括號

@someDecorator 
def someMethod(): 
    pass 

在第一代碼段括號

@someDecorator() 
def someMethod(): 
    pass 
+5

這些不是大括號,而是括號。大括號是'{}'。 –

+0

@DanielRoseman很好的提示,經常找到正確的單詞... – BendEg

+2

下面的很好的答案。值得指出的是,不同之處在於'foo'和'foo()'*之間的區別*,包括不在裝飾器中。 –

回答

35

someDecorator是常規裝飾:

@someDecorator 
def someMethod(): 
    pass 

相當於

someMethod = someDecorator(someMethod) 

在另一方面,在第二代碼段someDecorator是返回一個裝飾可調用:

@someDecorator() 
def someMethod(): 
    pass 

相當於

someMethod = someDecorator()(someMethod) 

如在評論中指出通過鄧肯,一些裝飾者被設計成雙向工作。這裏是一個非常基本實現這樣的裝飾的:

def someDecorator(arg=None): 
    def decorator(func): 
     def wrapper(*a, **ka): 
      return func(*a, **ka) 
     return wrapper 

    if callable(arg): 
     return decorator(arg) # return 'wrapper' 
    else: 
     return decorator # ... or 'decorator' 

pytest.fixture是一個更爲複雜的例子。

+9

在你的回答中增加一些值得說明的是,有些裝飾器被寫成兩種方式工作,例如, '@ pytest.fixture'可以直接用作裝飾器,或者可以用一些命名參數調用,在這種情況下它會返回裝飾器。 – Duncan

+0

可調用裝飾器的要點是什麼? AFAICT,'someDecorator()'將總是返回相同的結果,因爲它不接受任何參數(除非'someDecorator'持有一個狀態)。所以我認爲可調用的裝飾器持有狀態? – Utku