2016-02-23 54 views
34

Jaka jest różnica w Python podczas używania tego samego dekoratora z nawiasem lub bez nawiasów? Na przykład:Używanie dekoratora python z nawiasami lub bez nawiasów

bez nawiasów

@someDecorator 
def someMethod(): 
    pass 

z nawiasami

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

Nie są to nawiasy klamrowe, ale nawiasy. Klamrami są '{}'. –

+0

@DanielRoseman Dobra wskazówka, często walcząc ze znalezieniem właściwych słów ... – BendEg

+2

Świetna odpowiedź poniżej. Warto zauważyć, że różnica jest taka sama jak różnica między 'foo' i' foo() '* gdziekolwiek *, w tym nie w dekoratorze. –

Odpowiedz

35

someDecorator w pierwszym fragmencie kodu jest regularny dekorator:

@someDecorator 
def someMethod(): 
    pass 

jest równoważna

someMethod = someDecorator(someMethod) 

Z drugiej strony, someDecorator w drugim fragmencie kodu jest wymagalne, która zwraca dekorator:

@someDecorator() 
def someMethod(): 
    pass 

równoważny

someMethod = someDecorator()(someMethod) 

jak wskazał Duncan w komentarzach, niektórzy dekoratory są zaprojektowane do pracy w obie strony. Oto bardzo podstawowe wdrożenie takiego dekoratora:

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 jest bardziej skomplikowany przykład.

+9

Warto dodać do swojej odpowiedzi, aby wspomnieć, że niektóre dekoratory zostały napisane do pracy w obie strony, np. '@ pytest.fixture' może być użyty bezpośrednio jako dekorator, lub może wywoływany z niektórymi nazwanymi argumentami, w którym to przypadku zwraca dekorator. – Duncan

+0

Jaki jest sens dekoratorów wywoływalnych? AFAICT, 'someDecorator()' zawsze zwraca to samo, ponieważ nie przyjmuje żadnych argumentów (chyba że 'someDecorator' posiada stan). Więc przypuszczam, że dekoratorzy z windą utrzymują stan? – Utku