2012-09-06 18 views
9

Eventuali duplicati:
Understanding Python decoratorsDecoratori in pitone solo zucchero sintattico?

Sono abbastanza nuovo sull'utilizzo decoratori Python e da quanto ho capito la mia prima impressione che essi sono solo zucchero sintattico.

C'è un uso più profondo di questi per usi più complessi?

+2

C'è una risposta completa con esempi di utilizzo qui http://stackoverflow.com/questions/739654/understanding-python-decorators#answer-1594484 –

+0

Grazie. È davvero utile Non so come chiudere o cancellare questo post. Se qualcuno può farlo, sarebbe fantastico. – coredump

+0

Ed ecco un piccolo tutorial in modo da poter vedere esattamente quello che sono: https://www.codementor.io/python/tutorial/introduction-to-decorators – Sheena

risposta

10

Sì, è zucchero sintattico. Tutto può essere realizzato senza di loro, ma con poche altre righe di codice. Ma ti aiuta a scrivere codice più conciso.

Esempi:

from functools import wraps 

def requires_foo(func): 
    @wraps(func) 
    def wrapped(self, *args, **kwargs): 
     if not hasattr(self, 'foo') or not self.foo is True: 
      raise Exception('You must have foo and be True!!') 
     return func(self, *args, **kwargs) 
    return wrapped 

def requires_bar(func): 
    @wraps(func) 
    def wrapped(self, *args, **kwargs): 
     if not hasattr(self, 'bar') or not self.bar is True: 
      raise Exception('You must have bar and be True!!') 
     return func(self, *args, **kwargs) 
    return wrapped 

class FooBar(object): 

    @requires_foo     # Make sure the requirement is met. 
    def do_something_to_foo(self): 
     pass 

potremmo anche catena/stack le decoratori uno sopra l'altro.

class FooBar(object): 
    @requires_bar 
    @requires_foo     # You can chain as many decorators as you want 
    def do_something_to_foo_and_bar(self): 
     pass 

OK, abbiamo potuto finire con un sacco di decoratori uno sopra l'altro.

Lo so! Scriverò un decoratore che applica altri decoratori.

Così abbiamo potuto fare questo:

def enforce(requirements): 
    def wrapper(func): 
     @wraps(func) 
     def wrapped(self, *args, **kwargs): 
      return func(self, *args, **kwargs) 
     while requirements: 
      func = requirements.pop()(func) 
     return wrapped 
    return wrapper 

class FooBar(object): 
    @enforce([reguires_foo, requires_bar]) 
    def do_something_to_foo_and_bar(self): 
     pass 

Questo è un piccolo campione solo per giocare con.

2

mi piace molto la sintassi decoratore, perché rende il codice uber esplicito

Per esempio, in Django c'è questa decoratore login_required: https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

per iniettare il comportamento @login_required per una funzione/vista, tutto quello che devi fare è attaccare il decoratore ad esso (al contrario di mettere if: ... else: ... controllo delle espressioni ovunque ecc.)

Leggere il PEP!

http://www.python.org/dev/peps/pep-0318/

ha storia Losta sulle decisioni linguistiche che sono state fatte, e perché

Problemi correlati