Passer au contenu principal
eLearner.app
Module 5 · Leçon 2 sur 418/36 dans le cours~12 min
Leçons du module (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

Exercice#python.m5.l2.e1
Tentatives : 0Chargement…

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

Chargement de l'éditeur…
Afficher l'indice

return base ** exponent

Solution disponible après 3 tentatives

Esercizio di ripasso

Exercice#python.m5.l2.e2
Tentatives : 0Chargement…

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'])`.

Chargement de l'éditeur…
Afficher l'indice

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

Solution disponible après 3 tentatives

Sfida aggiuntiva

Exercice#python.m5.l2.e3
Tentatives : 0Chargement…

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

Chargement de l'éditeur…
Afficher l'indice

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

Solution disponible après 3 tentatives