In Python, i decoratori sono diventati parte del linguaggio a partire dalla versione 2.4, fornendo la possibilità di modificare il comportamento delle funzioni e delle classi. I decoratori per i parametri delle funzioni sono un pattern più complesso, che viene implementato manualmente, poiché non esiste un supporto sintattico diretto per tali decoratori nel linguaggio. Ma con l'ausilio delle annotazioni e della metaprogrammazione è possibile realizzarne la funzionalità.
I decoratori comuni influenzano l'intera funzione o metodo. A volte è necessario validare, registrare o modificare solo alcuni parametri della funzione a un determinato livello di astrazione. Ad esempio, controllare il tipo di argomento, trasformare il valore del parametro o imporre restrizioni sull'input.
I decoratori dei parametri delle funzioni vengono creati come metadati (ad esempio, tramite annotazioni di tipo) e vengono elaborati da un decoratore esterno. L'essenza del pattern è mantenere le informazioni necessarie sui parametri, e poi il decoratore "funzionale" le utilizza per elaborare i valori al momento della chiamata della funzione.
Esempio di codice:
import inspect from functools import wraps def positive_param(fn): """Annotazione per la verifica obbligatoria della positività dell'argomento.""" fn._positive = True return fn # Decoratore esterno completo def validate_decorator(func): spec = inspect.getfullargspec(func) @wraps(func) def wrapper(*args, **kwargs): bound_args = inspect.signature(func).bind(*args, **kwargs) for name, value in bound_args.arguments.items(): param = func.__annotations__.get(name, None) if getattr(param, '_positive', False) and value <= 0: raise ValueError(f"L'argomento {name} deve essere positivo") return func(*args, **kwargs) return wrapper @validate_decorator def deposit(amount: positive_param): print(f"Depositato {amount}") deposit(10) # OK deposit(-5) # ValueError
Caratteristiche chiave:
In cosa i decoratori dei parametri si differenziano dai decoratori standard delle funzioni?
Un decoratore standard avvolge l'intera funzione, indipendentemente dai parametri. Un decoratore per parametri si concentra su un argomento specifico e viene applicato solo a esso, il che richiede tecniche non standard di analisi e manipolazione della firma.
Possono i decoratori dei parametri essere implementati tramite la sintassi @ in Python, come avviene in TypeScript o C#?
No, in Python la sintassi dei decoratori tramite @ viene applicata solo a funzioni e classi, ma non a singoli parametri di funzione. Per i parametri si utilizzano le annotazioni, e poi si elabora l'annotazione durante l'incapsulamento della funzione.
È possibile applicare automaticamente i decoratori ai parametri degli argomenti della funzione senza un'annotazione esplicita?
No, Python non applica i decoratori ai parametri automaticamente, ma è possibile implementare un proprio meccanismo, ad esempio tramite una fabbrica di decoratori personalizzata che analizzerà la firma della funzione e sostituirà i valori dei parametri durante la chiamata.
Uno sviluppatore è convinto che si possa usare @ sul parametro, come in altri linguaggi, e scrive:
def f(@validate_positive x): ...
Pro:
Contro:
Uno sviluppatore utilizza un'annotazione e un decoratore esterno, come nell'esempio sopra, e gestisce i parametri tramite la firma e le annotazioni:
Pro:
Contro: