2016-02-23 9 views
34

Qual è la differenza in Python quando si utilizza lo stesso decoratore con o senza parentesi? Ad esempio:Uso di python decorator con o senza parentesi

Senza parentesi

@someDecorator 
def someMethod(): 
    pass 

Con parentesi

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

Queste non sono parentesi, ma parentesi. Le parentesi graffe sono '{}'. –

+0

@DanielRoseman buon suggerimento, spesso in difficoltà nel trovare le parole corrette ... – BendEg

+2

Ottima risposta qui sotto. Vale la pena sottolineare che la differenza è uguale alla differenza tra 'pippo' e' pippo() '* ovunque *, incluso non in un decoratore. –

risposta

35

someDecorator nel primo pezzo di codice è un decoratore regolare:

@someDecorator 
def someMethod(): 
    pass 

è equivalente a

someMethod = someDecorator(someMethod) 

D'altra parte, someDecorator nel secondo frammento di codice è un callable che restituisce un decoratore:

@someDecorator() 
def someMethod(): 
    pass 

è equivalente a

someMethod = someDecorator()(someMethod) 

Come sottolineato da Duncan nei commenti, alcuni i decoratori sono progettati per funzionare in entrambe le direzioni. Ecco una realizzazione piuttosto semplice di tale decoratore:

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 è un esempio più complesso.

+9

Potrebbe valere la pena aggiungere alla tua risposta per ricordare che alcuni decoratori sono stati scritti per funzionare in entrambi i modi, ad es. '@ pytest.fixture' può essere usato direttamente come decoratore, o chiamato forse con alcuni argomenti con nome, nel qual caso restituisce un decoratore. – Duncan

+0

Qual è il punto di decoratori chiamabili? AFAICT, 'someDecorator()' restituirà sempre la stessa cosa, poiché non accetta alcun argomento (a meno che 'someDecorator' non abbia uno stato). Quindi presumo che i decoratori callable abbiano uno stato? – Utku