Salta al contenuto
Note per Studenti Funzioni in Python

Funzioni in Python

In questa pagina 8
In questa pagina 8

Definizione e chiamata

python
def area_rettangolo(base, altezza):
    """Restituisce l'area di un rettangolo."""
    return base * altezza

a = area_rettangolo(3, 4)      # 12

Definizione (def, parametri e return)

Esempio. area_rettangolo(3, 4) restituisce 12; una funzione senza return restituisce None.

Parametri

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

saluta("Ada")                       # posizionale
saluta("Ada", "Buongiorno")
saluta("Ada", punto=".")            # argomento con nome (keyword)

Definizione (parametri predefiniti, args e kwargs)

  • I parametri con valore predefinito vanno dopo quelli senza.
  • *args raccoglie gli argomenti posizionali in più in una tupla; **kwargs quelli con nome in un dizionario.

Esempio. saluta("Ada", punto=".") restituisce 'Ciao, Ada.' e somma(1, 2, 3) restituisce 6.

python
def somma(*numeri):
    tot = 0
    for x in numeri:
        tot += x
    return tot

somma(1, 2, 3)      # 6

Trappola: default mutabile

Proprietà (valore predefinito 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 lista

Esempio. Con def aggiungi(x, lista=[]), la chiamata aggiungi(1) restituisce [1] e la successiva aggiungi(2) restituisce [1, 2]: la lista è la stessa.

Passaggio degli argomenti

Definizione (passaggio degli argomenti per riferimento a oggetto). 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.

Esempio. Con a, b = 5, [1] e f(a, b) che esegue n += 1 e lista.append(0), dopo la chiamata a == 5 e b == [1, 0].

python
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)

Definizione (ambito delle variabili LEGB). 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 (o nonlocal).
  • Leggere una globale da una funzione è lecito; assegnarla senza global crea una locale.

Esempio. Con global contatore, incrementa() porta contatore da 0 a 1; senza, contatore += 1 provoca UnboundLocalError.

python
contatore = 0
def incrementa():
    global contatore     # senza questa riga: UnboundLocalError
    contatore += 1

Le variabili globali modificate da funzioni rendono il codice difficile da seguire: meglio passare parametri e restituire valori.

Documentazione e tipi

python
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

Definizione (funzioni come oggetti e lambda). Le funzioni si possono assegnare, passare come argomenti e restituire.

Esempio. applica(abs, -3) restituisce 3 e sorted(["aaa", "b", "cc"], key=len) restituisce ['b', 'cc', 'aaa'].

python
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 campo

Progettare funzioni

Errori tipici

  • Dimenticare return: la funzione restituisce None e l'errore compare più avanti (TypeError: unsupported operand type(s) ... NoneType).
  • print al posto di return.
  • Chiamare senza parentesi: f è l'oggetto funzione, f() la chiamata.
  • Default mutabile condiviso tra chiamate.

Versione ripasso

Definizione e chiamata

Parametri

  • I parametri con valore predefinito vanno dopo quelli senza.
  • *args raccoglie gli argomenti posizionali in più in una tupla; **kwargs quelli con nome in un dizionario.

Trappola: default mutabile

Il valore predefinito viene valutato una volta sola, alla definizione.

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

Passaggio degli argomenti

Python passa riferimenti a oggetti (call by object reference).

Ambito delle variabili (scope)

Ordine di ricerca LEGB: Locale → Enclosing → Globale → Built-in.

  • Ogni nome assegnato dentro una funzione è locale, salvo global (o nonlocal).
python
contatore = 0
def incrementa():
    global contatore     # senza questa riga: UnboundLocalError
    contatore += 1

Documentazione e tipi

  • Docstring: prima stringa del corpo; la mostra help().
  • Annotazioni di tipo (type hint): documentazione non controllata dall'interprete.

Funzioni come oggetti e lambda

Le funzioni si possono assegnare, passare come argomenti e restituire.

  • lambda x: x * x: funzione anonima di una sola espressione.

Progettare funzioni

Errori tipici

  • Dimenticare return (NoneType) o usare print al posto di return.
  • Chiamare senza parentesi (f vs f()).
  • Default mutabile condiviso tra chiamate.

Esercizi su questo argomento

Teoria collegata