lettura facile

Come creare una funzione in Python

In questa lezione del corso Python ti spiego come si crea una funzione nel linguaggio Python

Cos'è una funzione? E' un blocco di codice che esegue un compito specifico e puoi richiamarlo più volte all'interno del programma principale. Ti permette di avere un programma più ordinato, compatto e facile da leggere.

In Python, le funzioni sono definite usando la parola chiave "def"

def nome_funzione(argomenti):
# codice della funzione
return valore_di_ritorno

Il codice contenuto nella funzione non viene eseguito al momento della definizione ma solo quando la funzione viene chiamata.

La funzione ha queste caratteristiche

  • la funzione deve avere un nome univoco
  • può accettare degli argomenti in entrata (input) tra parentesi tonde che utilizza durante l'esecuzione del blocco di codice
  • il codice all'interno della funzione devi digitarlo iniziando da una posizione più a destra rispetto alla definizione della funzione (indentazione)
  • la funzione restituisce un valore di ritorno (output) tramite l'istruzione return.

Nota. La funzione può anche non ricevere argomenti in input. In questo caso devi comunque indicare le parentesi tonde dopo il nome. Inoltre, la funzione può anche non restituire nulla come valore di ritorno. Quindi l'istruzione return può anche mancare. Ad esempio, puoi usare la funzione semplicemente per stampare qualcosa sullo schermo.

Un esempio pratico

Ti faccio un esempio pratico

Definisci una funzione che accetta due valori in entrata e li assegna alle variabili locali a, b

  1. # definizione della funzione
  2. def somma(a,b):
  3. risultato=a+b
  4. return risultato

La funzione somma i due valori a,b e assegna la somma alla variabile risultato.

Infine, restituisce il risultato al programma chiamante.

A questo punto aggiungi una chiamata alla funzione somma() in cui gli passi i valori 2 e 3

  1. # definizione della funzione
  2. def somma(a,b):
  3. risultato=a+b
  4. return risultato
  5.  
  6. # prima chiamata
  7. s = somma(2,3)
  8. print(s)

Quando esegui il programma, la funzione somma() viene chiamata con gli argomenti a=2 e b=3, restituendo 5 come risultato.

Quindi, il programma principale stampa il risultato sullo schermo

5

Ora aggiungi un'altra chiamata alla funzione in cui passi alla funzione somma() i valori a=4 e b=5

  1. # definizione della funzione
  2. def somma(a,b):
  3. risultato=a+b
  4. return risultato
  5.  
  6. # prima chiamata
  7. s = somma(2,3)
  8. print(s)
  9.  
  10. # seconda chiamata
  11. s = somma(4,5)
  12. print(s)

In questo caso la funzione viene chiamata due volte.

  • Nella prima chiamata somma(2,3) la funzione restituisce 5
  • Nella seconda chiamata somma(4,5) la funzione restituisce 9

Quindi, l'output del programma è

5
9

L'utilizzo delle funzioni ti permette di scrivere il codice una sola volta e richiamarlo solo quando ti serve.

In questo modo eviti di scriverlo più volte.

Nota. Se in futuro vorrai modificare il codice del programma, ad esempio per calcolare la differenza anziché la somma, ti basterà modificare una sola volta la funzione.

I parametri della funzione

I parametri di una funzione in Python sono le variabili elencate tra le parentesi nella definizione della funzione. Servono a passare valori alla funzione.

  1. def somma(a,b):
  2.    print(a+b)
  3.  
  4. c=somma(2,3)

In questo esempio le etichette "a" e "b" dichiarate tra parentesi sono i parametri della funzione mentre i valori 2 e 3 passati sono detti argomenti.

L'insieme dei parametri della funzione (a,b) è, invece, detta signature.

In generale i parametri sono passati per posizione, da sinistra verso destra, seguendo il loro ordine nella signature. L'accoppiamento dei parametri agli argomenti è detto matching.

Ad esempio, il primo valore della chiamata (2) viene assegnato al primo parametro (a) della funzione e via dicendo.

Questo passaggio è detto matching per posizione.

  1. def somma(a,b):
  2.    print(a+b)
  3.  
  4. c=somma(2,3)

In alternativa, puoi passare i valori ai parametri in base al loro nome, piuttosto che alla loro posizione.

Questo passaggio è detto matching per keyword.

  1. def somma(a,b):
  2.    print(a+b)
  3.  
  4. c=somma(b=3, a=2)

In entrambi i casi il numero dei parametri della funzione deve essere uguale al numero degli argomenti.

Puoi anche passare i parametri in modo combinato, alcuni per posizione e altri per keyword.

Ricorda però di inserire i parametri per posizione sempre prima rispetto ai parametri per keyword.

  1. def somma(a,b):
  2.    print(a+b)
  3.  
  4. c=somma(2,b=3)

Python ti permette anche di indicare dei valori di default dei parametri.

Il valore di default viene usato dalla funzione solo se nessun valore viene passato per quel parametro.

In questo caso, però, ricorda di inserire i parametri con valori di default sempre in coda, dopo gli altri parametri della funzione.

  1. def somma(a,b=0):
  2.    print(a+b)
  3.  
  4. c=somma(2)

Se non sai quanti parametri verranno passati alla tua funzione, puoi usare *args, che raccoglie tutti i parametri posizionali aggiuntivi in una tupla.

  1. def somma(*args):
  2.    pass

In alternativa, puoi usare *kwargs che ti permette di gestire un numero arbitrario di parametri parola-chiave, raccolti in un dizionario. 

  1. def somma(*kwargs):
  2.    pass

Per indicare che alcuni parametri devono essere passati per nome, puoi usare il simbolo dell'asterisco *.

Dopo un parametro *, tutti i parametri successivi devono essere specificati usando il loro nome.

  1. def somma(a, *, b, c):
  2.    pass

Inoltre, dalla versione 3.8 di Python, puoi anche specificare i parametri che devono essere passati per posizione, mettendo un `/` nella lista dei parametri. 

  1. def somma(a, b, /, c, d)::
  2.    pass

In questo caso i parametri a e b devono essere passati solo posizionalmente

Gli oggetti sono passati per riferimento

Ricorda che, quando passi un oggetto, Python passa il riferimento all'indirizzo di memoria dell'oggetto e non una copia dell'oggetto.

Quindi, la funzione può modificare l'oggetto originale.

Ecco un esempio pratico

  1. def foo(x):
  2.   x.append(4)
  3.   return x
  4.  
  5. myList=[1,2,3]
  6. y=foo(myList)
  7. print(y)
  8. print(myList)

Questo programma passa il riferimento di una lista alla funzione foo() e gli aggiunge un elemento.

In questo caso la funzione modifica la lista originale.

[1, 2, 3, 4]
[1, 2, 3, 4]

Per evitare che una funzione modifichi l'oggetto originale passato come parametro, ti consiglio di creare una copia profonda (deep copy) dell'oggetto e passare quest'ultima alla funzione.

Questo approccio ti assicura che eventuali modifiche apportate all'interno della funzione non influiscano sull'oggetto originale.

L'istruzione return

L'istruzione return restituisce il valore di ritorno della funzione al programma chiamante.

Ad esempio, guarda questa funzione

  1. def quadrato(x):
  2.   x=x**2
  3.   return x
  4.  
  5. y=quadrato(3)
  6. print(y)

La funzione riceve in ingresso il valore x, calcola il quadrato del valore e lo restituisce al punto del programma dove è stata chiamata.

In questo caso lo script stampa il quadrato di 3, ossia 9

9

Ricorda però che una funzione restituisce sempre il risultato, sia in modo esplicito che implicito.

L'istruzione return ti permette di restituire il valore di ritorno in modo esplicito.

Tuttavia, se l'istruzione return non viene eseguita o manca del tutto, la funzione restituisce l'oggetto None in modo implicito.

Ad esempio, prova a togliere il return x dalla funzione e osserva cosa succede.

  1. def quadrato(x):
  2.   x=x**2
  3.  
  4. y=quadrato(3)
  5. print(y)

In questo caso la funzione riceve il valore in ingresso (x=3), calcola il quadrato ma non restituisce il risultato.

Non essendoci l'istruzione return, la funzione restituisce l'oggetto None

None

Inoltre, ricorda che la funzione può restituire un solo valore di ritorno tramite l'istruzione return.

Tuttavia, se vuoi che restituisca più risultati c'è un escamotage: puoi sempre impacchettarli in un unico oggetto come una lista o una tupla.

Ad esempio, questa funzione calcola il quadrato e il cubo del valore in ingresso (x=3)

  1. def quadrato(x):
  2.   y1=x**2
  3.   y2=x**3
  4.   return (y1,y2)
  5.  
  6. y=quadrato(3)
  7. print(y)

In questo caso la funzione impacchetta i due valori di ritorno y1=9 e y2=27 in una tupla (y1,y2) e la restituisce al programma chiamante

(9, 27)

A questo punto non ti resta altro da fare che leggere i valori all'interno della tupla.

print("Il quadrato di x è "+ str(y[0]))
print("Il cubo di x è "+ str(y[1]))

Il risultato in output è il seguente:

Il quadrato di x è 9
Il cubo di x è 27

In questo modo puoi restituire due o più risultati dalla stessa funzione.

L'etichetta della funzione

Ricorda che le funzioni sono oggetti del tipo Function e il nome della funzione (o etichetta) è semplicemente il riferimento all'oggetto funzione.

Quindi, se riutilizzi la stessa etichetta in altri modi durante la sessione o il programma, ad esempio per assegnare un valore alla variabile, non è più possibile richiamare la funzione.

Ad esempio, considera questo script

  1. # definizione della funzione
  2. def somma(a,b):
  3. risultato=a+b
  4. return risultato
  5.  
  6. # prima chiamata
  7. s = somma(2,3)
  8. print(s)
  9.  
  10. # riutilizzo dell'etichetta
  11. somma=5
  12.  
  13. # seconda chiamata
  14. s = somma(4,5)
  15. print(s)

In questo caso l'etichetta "somma" della funzione viene riutilizzata per assegnare un valore a una variabile.

La prima chiamata alla funzione viene svolta normalmente, mentre la seconda restituisce un errore perché il riferimento alla funzione si è perso.

5
Traceback (most recent call last):
  File "/home/main.py", line 14, in <module>
    s = somma(4,5)
TypeError: 'int' object is not callable

Pertanto, una volta definito il nome della funzione, è opportuno fare attenzione e non riutilizzarlo all'interno dello stesso programma.

La docstring della funzione

Se inserisci un letterale come prima istruzione nel blocco di codice della funzione, questa stringa diventa accessibile tramite l'attributo __doc__ della funzione o la funzione help().

Questa stringa è detta docstring ed è estremamente utile per fornire documentazione e aiuto sull'utilizzo della funzione ed è anche detta .

Ad esempio, scrivi questa funzione

  1. # definizione della funzione
  2. def somma(a,b):
  3.     """Questa funzione calcola la somma"""
  4.     risultato=a+b
  5.     return risultato
  6.  
  7. print(somma.__doc__)

In questo caso la prima istruzione nella funzione è una stringa.

Quando provi a stampare l'attributo somma.__doc__, Python ti restituisce la docstring.

Questa funzione calcola la somma

In alternativa, puoi accedere alla docstring usando la funzione help()

help(somma)

In entrambi i casi viene visualizzato il contenuto della stringa informativa.

Help on function somma in module __main__:

somma(a, b)
    Questa funzione calcola la somma

Le docstring in Python ti forniscono una pratica modalità per documentare il funzionamento e lo scopo di una funzione, classe o modulo direttamente nel codice.




Non hai risolto il tuo problema? Scrivi una domanda




FacebookTwitterLinkedinLinkedin