ProgrammazioneSviluppatore Backend

Come funziona il meccanismo di gestione degli argomenti posizionali e per nome (positional and keyword arguments) in Python? Quali sono le sfumature dell'ordine degli argomenti durante la definizione e la chiamata della funzione, e a cosa servono i parametri solo posizionali e solo per nome?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

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.

Tipi di parametri

  1. Posizionali (di solito vengono prima): i valori vengono passati in ordine di indicazione.
  2. Per nome: vengono specificati esplicitamente tramite nome.
  3. Solo posizionali: vengono dichiarati prima del simbolo / (Python 3.8+), non possono essere specificati per nome.
  4. Solo per nome: vengono dichiarati dopo *, 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

Sfumature

  • Ordine dei parametri: (only-positional) / (positional-or-keyword) * (only-keyword)
  • In caso di ordine errato degli argomenti — SyntaxError o TypeError.
  • *args raccoglie argomenti posizionali aggiuntivi; **kwargs — per nome.

Domanda trabocchetto.

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?

Risposta:

  • Per la funzione 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.
  • È possibile specificare i parametri per nome se non sono definiti come solo posizionali.
  • Se la funzione è dichiarata come def f(a, b, /, c):, allora a e b possono essere passati solo per posizione.

Esempio:

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

Esempi di errori reali dovuti alla mancanza di conoscenza delle sfumature dell'argomento


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.