// data & ai · giornale tecnico MILANO ● LIVE 00:00:00

Basta catene di if-else: il registry pattern in Python per il dispatch della logica

Le lunghe catene if/elif/else violano l’Open/Closed Principle e diventano ingestibili. Il registry pattern le sostituisce con una tabella di lookup che i componenti popolano da soli, tramite dizionari, decoratori o __init_subclass__.

Quasi ogni codebase Python ha quella funzione partita piccola con due o tre rami che, un anno dopo, e’ diventata una catena di if/elif/else da 200 righe che nessuno vuole toccare. Funziona, ma viola l’Open/Closed Principle: ogni nuovo caso costringe a riaprire, ritestare e rivedere codice gia’ funzionante. Un articolo di KDnuggets mostra un’alternativa piu’ pulita ed estensibile, il registry pattern, utile a chiunque scriva dispatcher di modelli, parser o handler nel proprio data stack.

Cosa non va nelle catene if-else

Una lunga catena condizionale fallisce in modi precisi: viola l’Open/Closed Principle, accumula logica non correlata in un solo punto, scala male (venti rami sono venti cose da scorrere ogni volta che debugghi il terzo) e non e’ estensibile dall’esterno. Se distribuisci una libreria con un get_model() hardcoded, i tuoi utenti non possono aggiungere il proprio modello senza monkey-patching o fork. Il registry pattern ribalta la relazione: invece che il dispatcher conoscere ogni opzione, ogni opzione si annuncia al dispatcher. In pratica e’ una tabella di lookup centrale, quasi sempre un dizionario, che mappa chiavi a oggetti (funzioni, classi, istanze).

Dal dizionario al decoratore alla classe

Il primo passo e’ sostituire la catena con un semplice dizionario: il dispatch diventa O(1), le opzioni sono introspezionabili con list(MODEL_REGISTRY) e il dispatcher non cambia mai. Resta un problema: ogni nuovo modello richiede ancora di editare il dict. La versione da usare quotidianamente sposta la registrazione in un decoratore, cosi’ ogni funzione dichiara la propria chiave dove viene definita. Il dispatcher process_payment diventa di quattro righe e non crescera’ mai: per aggiungere Apple Pay basta scrivere una nuova funzione con @register("apple_pay"), in qualsiasi file, senza liste centrali da modificare ne’ conflitti di merge. Quando i registry si moltiplicano, conviene incapsulare il boilerplate in una piccola classe Registry che offre gratis rilevamento delle collisioni, messaggi d’errore migliori e un’API pulita. A quel punto una pipeline di trasformazioni testuali diventa pura configurazione: una lista di stringhe che potrebbe arrivare da un file YAML, un argomento CLI o una riga di database.

Auto-registrazione e casi d’uso reali

Quando il registry contiene classi anziche’ funzioni, l’hook __init_subclass__ (disponibile da Python 3.6) scatta automaticamente alla definizione di ogni sottoclasse, che si registra senza alcun decoratore: e’ cosi’ che molti framework costruiscono i loro sistemi di plugin. Il pattern e’ la spina dorsale di strumenti gia’ in uso: Hugging Face Transformers, Detectron2 e MMDetection lo usano per scegliere modello o ottimizzatore per nome in un file YAML; le route di Flask e i comandi di Click sono registry travestiti; pytest, Airflow e i sistemi “metti un file nella cartella e funziona” collezionano componenti a import time.

  • La registrazione avviene solo all’import: assicurati che i moduli con i decoratori vengano effettivamente importati, ad esempio da un __init__.py o con un discovery loop.
  • Proteggiti dalle sovrascritture silenziose sollevando un errore sulle chiavi duplicate, ed esponi sempre le chiavi disponibili nei messaggi d’errore.
  • Non usarlo troppo presto: per due o tre rami stabili, o per condizioni a intervalli anziche’ chiavi discrete, un semplice condizionale resta piu’ chiaro.

Fonte: Stop Using If-Else Chains: the Registry Pattern in Python — https://www.kdnuggets.com/stop-using-if-else-chains-use-the-registry-pattern-in-python-instead

Condividi X Facebook LinkedIn WhatsApp Email

// scritto da

Fernando

Hai qualcosa da aggiungere? Unisciti alla discussione.

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Altri dell'autore

dalla stessa firma