Domanda

Di recente ho iniziato a sperimentare con i decoratori di Python (e le funzioni di ordine superiore) perché sembrava che avrebbero potuto rendere i miei test di unità Django più concisi. ad esempio, invece di scrivere:

def visit1():
    login()
    do_stuff()
    logout()

Potrei invece farlo

@handle_login
def visit1():
    do_stuff()

Tuttavia, dopo alcuni esperimenti, ho scoperto che i decoratori non sono così semplici come speravo. Innanzitutto, sono stato confuso dalla diversa sintassi del decoratore che ho trovato in diversi esempi, fino a quando ho imparato che i decoratori si comportano in modo molto diverso quando accetta argomenti . Poi ho provato a decorare un metodo e alla fine ho scoperto che non funzionava perché prima dovevo trasforma il mio decoratore in un descrittore aggiungendo un metodo __get__. Durante l'intero processo sono finito confuso più di un paio di volte e trovo ancora che il debug di questo & Quot; decorato & Quot; il codice è più complicato di quanto non sia normalmente per Python. Ora sto rivalutando se ho davvero bisogno di decoratori nel mio codice, poiché la mia motivazione iniziale era quella di risparmiare un po 'di battitura, non perché c'era qualcosa che richiedesse davvero funzioni di ordine superiore.

Quindi la mia domanda è: i decoratori dovrebbero essere usati liberamente o con parsimonia? È sempre più Pythonic per evitare di usarli?

È stato utile?

Soluzione

I decoratori stanno bene al loro posto e sicuramente non devono essere evitati - se del caso ;-). Vedo la tua domanda come essenzialmente & Quot; OK, quindi quando sono si appropriano di & Quot ;?

L'aggiunta di un prefisso e / o codice postfisso attorno ad alcuni ma non a tutti i metodi di alcune classi è un buon esempio. Se fossero tutti metodi, un decoratore di classe per avvolgere tutti i metodi sarebbe meglio che ripetere @thisonetoo all'infinito ;-). Se è una volta in una luna blu, non vale la pena rifattorizzare gli involucri (decoratori o altro). Nel mezzo, c'è un grande terreno in cui i decoratori sono davvero adatti.

Si riduce a una delle regole d'oro della programmazione: DRY, per Don't Repeat Yourself. Quando vedi che il tuo codice diventa ripetitivo, dovresti rielaborare la ripetizione - e i decoratori sono uno strumento eccellente per questo, anche se sono tutt'altro che unici (metodi e funzioni ausiliari, metaclassi personalizzati, generatori e altri iteratori, gestori di contesto ... molte delle funzionalità che abbiamo aggiunto a Python negli ultimi anni possono essere pensate come aiutanti a SECCO, modi più semplici e fluidi per fattorizzare questa o quella frequente forma di ripetizione!).

Se non c'è ripetizione, non c'è un vero richiamo per il refactoring, quindi (in particolare) non c'è un reale bisogno di decoratori - in questi casi, YAGNI (Y'Ain't Gonna Need It) può battere DRY; -).

Altri suggerimenti

Alex ha già risposto abbastanza bene alla tua domanda, ciò che aggiungerei sono i decoratori, rendere il tuo codice MOLTO più facile da capire. (A volte, anche se lo fai solo una volta).

Ad esempio, inizialmente, scrivo le mie viste Django, senza pensare affatto all'autorizzazione. E quando, ho finito di scriverli, posso vedere quali utenti hanno bisogno di utenti autorizzati e ho appena messo un @login_required per loro.

Quindi chiunque viene dopo di me può vedere a colpo d'occhio quali viste sono protette da autenticazione.

E, naturalmente, sono molto più ASCIUTTI e lo mettono ovunque.

se non request.user.is_authenticated ():     restituire HttpResponseREdiect (..)

I decoratori sono un modo per estrarre un aspetto dal codice.

Programmazione orientata agli aspetti ti diranno che ci sono così tanti aspetti comuni che AOP è essenziale e centrale. In effetti, puoi leggere un dibattito sciocco su questo argomento qui:

Programmazione orientata agli aspetti vs. Programmazione orientata agli oggetti

Esistono alcuni casi d'uso comuni per AOP. Puoi leggerne alcuni qui:

Usi AOP (Aspect Oriented Programming) nel software di produzione?

Ci sono alcune preoccupazioni trasversali per le quali i decoratori sono utili.

  • Controlli di accesso (" security ") Autenticazione, autorizzazione, autorizzazioni, proprietà

  • Registrazione (inclusi aiuti per il debug e controllo)

  • Caching (spesso un'implementazione di Memoization )

  • Una certa gestione degli errori potrebbe essere un aspetto comune e quindi adatto all'implementazione di Decorator.

Ci sono pochissimi altri modelli di design che sono veramente trasversali e meritano un decoratore AOP.

Se hai lo stesso codice all'inizio e alla fine di molte funzioni, penso che ciò giustificherebbe la complessità aggiunta dell'uso di un decoratore.

Piuttosto come usare un modello carino (ma forse complesso) per un sito Web con molte pagine, fa davvero risparmiare tempo e aggiunge chiarezza alla fine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top