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
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:
def f(a, b=1): # OK
def f(a=1, b): # SyntaxErrorKeyword arguments
Puoi passare argomenti per nome, in qualunque ordine, rendendo la chiamata più leggibile:
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 keywordRegola d'oro: in una chiamata, i posizionali vanno PRIMA dei keyword.
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.
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:
def aggiungi(elemento, lista=None):
if lista is None:
lista = []
lista.append(elemento)
return listaIl 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:
def aggiungi(x, lista=None):
if lista is None:
lista = []
lista.append(x)
return listaProva tu
Definisci `power(base, exponent=2)` che restituisce base ** exponent. Calcola `square = power(5)` e `cube = power(5, exponent=3)`. Valuta `(square, cube)`.
Mostra suggerimento
return base ** exponent
Soluzione disponibile dopo 3 tentativi
Esercizio di ripasso
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'])`.
Mostra suggerimento
Usa None come default e crea la lista dentro la funzione.
Soluzione disponibile dopo 3 tentativi
Sfida aggiuntiva
Definisci una funzione `greet(name, message="Hello")` che restituisca la stringa formattata `"{message}, {name}!"`. Testa la funzione chiamando `greet("Bob")` come ultima espressione.
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