Vai al contenuto
eLearner.app
Modulo 5 · Lezione 3 di 419/36 nel corso~12 min
Lezioni del modulo (3/4)

*args e **kwargs

A volte vuoi una funzione che accetti un numero variabile di argomenti. Python ti dà due strumenti: *args (raccoglie i posizionali in una tuple) e **kwargs (raccoglie i keyword in un dict).

*args: posizionali variabili

Python
def somma_tutto(*nums):
    totale = 0
    for n in nums:
        totale += n
    return totale

somma_tutto(1, 2, 3)         # 6
somma_tutto(1, 2, 3, 4, 5)   # 15
somma_tutto()                # 0

Dentro la funzione, nums è una tuple con tutti i valori passati. Il nome è convenzione: *args è il più comune, ma *nums o *valori sono perfettamente validi.

**kwargs: keyword variabili

Python
def crea_config(**opzioni):
    return opzioni

crea_config(debug=True, port=8080)
# {'debug': True, 'port': 8080}

Dentro la funzione, opzioni è un dict con {nome_param: valore}.

Combinare tutto

L'ordine fisso è: **parametri normali, *args, parametri con default, **kwargs**.

Python
def f(primo, *args, opzione="x", **kwargs):
    print(primo, args, opzione, kwargs)

f(1, 2, 3, opzione="y", extra=10)
# 1 (2, 3) y {'extra': 10}

Unpacking nella chiamata: * e **

Lo stesso operatore funziona al contrario: per "esplodere" una lista/tuple in argomenti posizionali o un dict in keyword argomenti.

Python
def punto(x, y, z):
    return (x, y, z)

coords = [1, 2, 3]
punto(*coords)        # punto(1, 2, 3)  →  (1, 2, 3)

opts = {"x": 1, "y": 2, "z": 3}
punto(**opts)         # punto(x=1, y=2, z=3)

Pattern wrapper

Python
def log_chiamata(fn, *args, **kwargs):
    print(f"chiamo {fn.__name__} con {args=} {kwargs=}")
    return fn(*args, **kwargs)

log_chiamata(max, 3, 1, 2)             # chiama max(3, 1, 2)
log_chiamata(sorted, [3, 1, 2], reverse=True)

Ordine dei parametri nella firma

Quando definisci una funzione che accetta molteplici tipi di argomenti, devi rispettare un ordine preciso nella firma:

  1. Parametri posizionali standard.
  2. Parametro variadico *args.
  3. Parametri con valori di default.
  4. Parametro variadico **kwargs.

Prova tu

Esercizio#python.m5.l3.e1
Tentativi: 0Caricamento…

Definisci `average(*nums)` che restituisce la media aritmetica (somma / quantità). Chiamala con 10, 20, 30 e assegna a `m`. Valuta `m`.

Caricamento editor…
Mostra suggerimento

sum(nums) / len(nums)

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#python.m5.l3.e2
Tentativi: 0Caricamento…

Data la funzione `def point(x, y, z): return x + y + z` e il dict `coords = {'x': 1, 'y': 2, 'z': 3}`, chiama point unpackando coords e assegna il risultato a `s`. Valuta `s`.

Caricamento editor…
Mostra suggerimento

point(**coords)

Soluzione disponibile dopo 3 tentativi

Sfida aggiuntiva

Esercizio#python.m5.l3.e3
Tentativi: 0Caricamento…

Scrivi una funzione `multiply_all(*args)` che restituisca il prodotto di tutti i numeri passati come argomenti. Se non viene passato alcun argomento, deve restituire `1`. Valuta infine la chiamata `multiply_all(2, 3, 4)`.

Caricamento editor…
Mostra suggerimento

Usa un ciclo for per scorrere gli elementi all'interno di args ed accumulare il prodotto.

Soluzione disponibile dopo 3 tentativi