In Python, è possibile dichiarare parametri di quattro tipi in una funzione: posizionali, per nome (keyword), solo posizionali (positional-only) e solo per nome (keyword-only). La loro differenza influisce sul modo in cui i valori vengono passati durante la chiamata della funzione.
/ (Python 3.8+), non possono essere specificati per nome.*, possono essere specificati solo per chiave.# Esempio di tutti i tipi def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # Errore: a, b - solo posizionali
SyntaxError o TypeError.*args raccoglie argomenti posizionali aggiuntivi; **kwargs — per nome.Qual è la differenza tra le dichiarazioni di funzioni:
def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...
è vero che tutte queste funzioni possono essere chiamate sia con argomenti posizionali che per nome?
def f(a, b, c): non è possibile chiamarla solo con argomenti per nome, perché tutto può essere passato sia per posizione che per chiave, ma tutti gli argomenti sono obbligatori.def f(a, b, /, c):, allora a e b possono essere passati solo per posizione.def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10 per default f(a=1, b=2, c=3) # OK # Ma ecco: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # Errore! a e b solo posizionali
Storia
Uno sviluppatore ha implementato una funzione che per convenzione doveva accettare parametri esclusivamente per nome: logging con numerosi parametri, alcuni opzionali. Ma ha dimenticato di dichiarare * — e gli utenti hanno accidentalmente passato parametri in ordine sbagliato per posizione, portando a logging errato e errori difficili da tracciare.
Storia
In un progetto con REST API, a causa di un accordo implicito sull'ordine degli argomenti (usando *args e non limitando i parametri per nome) hanno smesso di funzionare le richieste dopo l'implementazione di una nuova versione del client — perché args si erano spostati. Hanno risolto introducendo espliciti * e specificando solo argomenti per nome.
Storia
In un grande progetto aziendale, la funzione è stata ampliata con nuovi parametri con valori di default, ma a causa di una chiamata errata con valori posizionali, il vecchio codice ha iniziato a inserire valori in altri parametri, causando un'elaborazione dei dati non corretta. Si è scoperto che i parametri dovevano essere solo per nome.