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

Parametri di default e keyword

I parametri di una funzione possono avere valori di default: se il chiamante non li passa, vengono usati i default. Inoltre puoi chiamare una funzione passando i parametri per nome (keyword arguments).

Parametri di default

Python
def saluta(nome, saluto="Ciao"):
    return f"{saluto}, {nome}!"

saluta("Ada")              # 'Ciao, Ada!'
saluta("Ada", "Hello")     # 'Hello, Ada!'

I parametri con default devono venire dopo quelli senza:

Python
def f(a, b=1):     # OK
def f(a=1, b):     # SyntaxError

Keyword arguments

Puoi passare argomenti per nome, in qualunque ordine, rendendo la chiamata più leggibile:

Python
def crea_utente(nome, eta, attivo=True):
    return {"nome": nome, "eta": eta, "attivo": attivo}

crea_utente("Ada", 36)
crea_utente(nome="Ada", eta=36, attivo=False)
crea_utente(eta=36, nome="Ada")     # ordine libero quando sono tutti keyword

Regola d'oro: in una chiamata, i posizionali vanno PRIMA dei keyword.

Python
crea_utente("Ada", eta=36)            # OK
crea_utente(nome="Ada", 36)           # SyntaxError

⚠️ Il pitfall del mutable default

MAI usare un oggetto mutabile (lista, dict, set) come valore di default: il default viene valutato UNA SOLA VOLTA alla definizione della funzione, e condiviso tra tutte le chiamate.

Python
def aggiungi(elemento, lista=[]):   # BUG!
    lista.append(elemento)
    return lista

aggiungi(1)    # [1]
aggiungi(2)    # [1, 2]    !!! non [2] come ti aspetteresti
aggiungi(3)    # [1, 2, 3]

Il pattern corretto: usare None come sentinella e crearla dentro:

Python
def aggiungi(elemento, lista=None):
    if lista is None:
        lista = []
    lista.append(elemento)
    return lista

Il pericolo dei parametri di default mutabili

Non usare mai oggetti mutabili (come liste o dizionari) come valori di default di un parametro: ad esempio def aggiungi(x, lista=[]). Il valore di default viene creato una sola volta all'avvio del programma, quindi chiamate successive condivideranno lo stesso oggetto mutabile! La best practice è usare None:

Python
def aggiungi(x, lista=None):
    if lista is None:
        lista = []
    lista.append(x)
    return lista

Prova tu

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

Definisci `power(base, exponent=2)` che restituisce base ** exponent. Calcola `square = power(5)` e `cube = power(5, exponent=3)`. Valuta `(square, cube)`.

Caricamento editor…
Mostra suggerimento

return base ** exponent

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

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

Definisci `create_record(name, values=None)` che, se values è None, usa una lista vuota nuova. Aggiungi 1 a values e ritorna il record dict {'name': name, 'values': values}. Chiamala due volte senza passare values e assegna a `a` e `b`. Valuta `(a['values'], b['values'])`.

Caricamento editor…
Mostra suggerimento

Usa None come default e crea la lista dentro la funzione.

Soluzione disponibile dopo 3 tentativi

Sfida aggiuntiva

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

Definisci una funzione `greet(name, message="Hello")` che restituisca la stringa formattata `"{message}, {name}!"`. Testa la funzione chiamando `greet("Bob")` come ultima espressione.

Caricamento editor…
Mostra suggerimento

Usa un valore di default message="Hello" nel parametro e una f-string per il valore di ritorno.

Soluzione disponibile dopo 3 tentativi