Funzioni in Python
In questa pagina 8
Definizione e chiamata
def area_rettangolo(base, altezza):
"""Restituisce l'area di un rettangolo."""
return base * altezza
a = area_rettangolo(3, 4) # 12defcrea un oggetto funzione e lo lega al nome. Il corpo viene eseguito solo alla chiamata.- Parametri (nella definizione) e argomenti (nella chiamata).
return exprtermina la funzione e restituisce il valore; senzareturn(o conreturnvuoto) restituisceNone.- Più valori:
return q, rrestituisce una tupla, che si spacchetta conq, r = f(...)(vedi Tuple e unpackingtuple come sequenze immutabili; quando usarle al posto delle liste; spacchettamento, scambio, asterisco; tuple come valori di ritorno multipli e come chiavi di dizionario.Tuple e unpacking →).
Parametri
def saluta(nome, saluto="Ciao", punto="!"):
return f"{saluto}, {nome}{punto}"
saluta("Ada") # posizionale
saluta("Ada", "Buongiorno")
saluta("Ada", punto=".") # argomento con nome (keyword)- I parametri con valore predefinito vanno dopo quelli senza.
*argsraccoglie gli argomenti posizionali in più in una tupla;**kwargsquelli con nome in un dizionario.
def somma(*numeri):
tot = 0
for x in numeri:
tot += x
return tot
somma(1, 2, 3) # 6Trappola: default mutabile
Il valore predefinito viene valutato una volta sola, alla definizione:
def aggiungi(x, lista=[]): # SBAGLIATO: la stessa lista è condivisa tra le chiamate
lista.append(x)
return lista
def aggiungi(x, lista=None): # corretto
if lista is None:
lista = []
lista.append(x)
return listaPassaggio degli argomenti
Python passa riferimenti a oggetti (call by object reference): il parametro diventa un nuovo nome per lo stesso oggetto dell'argomento.
- Riassegnare il parametro non tocca il chiamante.
- Modificare sul posto un argomento mutabile è visibile al chiamante.
def f(n, lista):
n += 1 # rilega il nome locale n: il chiamante non lo vede
lista.append(0) # modifica l'oggetto condiviso: il chiamante lo vede
a, b = 5, [1]
f(a, b)
print(a, b) # 5 [1, 0]Confronto con il C (passaggio per valore e puntatori): Funzioni in CDefinizione e prototipo di una funzione C, tipo di ritorno e void, passaggio dei parametri sempre per valore, variabili locali, globali e static, file header e compilazione separata, funzioni ricorsive.Funzioni in C →.
Ambito delle variabili (scope)
Un nome viene cercato nell'ordine LEGB: Locale (funzione corrente) → Enclosing (funzioni che la contengono) → Globale (modulo) → Built-in.
- Ogni nome assegnato dentro una funzione è locale a quella funzione, salvo dichiarazione
global(ononlocal). - Leggere una globale da una funzione è lecito; assegnarla senza
globalcrea una locale.
contatore = 0
def incrementa():
global contatore # senza questa riga: UnboundLocalError
contatore += 1Le variabili globali modificate da funzioni rendono il codice difficile da seguire: meglio passare parametri e restituire valori.
Documentazione e tipi
def media(valori: list[float]) -> float:
"""Media aritmetica di una lista non vuota."""
return sum(valori) / len(valori)- La docstring è la prima stringa del corpo; la mostra
help(media). - Le annotazioni di tipo (type hint) sono documentazione verificabile da strumenti esterni (Pylance, mypy): l'interprete non le controlla.
Funzioni come oggetti e lambda
Le funzioni si possono assegnare, passare come argomenti e restituire.
def applica(f, x):
return f(x)
applica(abs, -3) # 3
quadrato = lambda x: x * x # funzione anonima di una sola espressione
sorted(parole, key=len) # ordina per lunghezza
sorted(studenti, key=lambda s: s[1]) # ordina tuple per il secondo campoProgettare funzioni
- Una funzione, un compito; nome che dice che cosa restituisce o che cosa fa.
- Specificare precondizioni (che cosa deve valere sugli argomenti) e postcondizioni (che cosa garantisce il risultato) nella docstring.
- Preferire funzioni che restituiscono un valore a funzioni che stampano: si possono riusare e testare (vedi Debugging e testingTipi di errore, metodo per localizzare un bug, lettura del traceback, stampe di controllo, debugger (VS Code, pdb, gdb), assert e strumenti per la memoria in C; test di unità, casi limite e partizioni, doctest e unittest.Debugging e testing →).
Errori tipici
- Dimenticare
return: la funzione restituisceNonee l'errore compare più avanti (TypeError: unsupported operand type(s) ... NoneType). printal posto direturn.- Chiamare senza parentesi:
fè l'oggetto funzione,f()la chiamata. - Default mutabile condiviso tra chiamate.