Funzioni

Una funzione è un frammento di codice associato a un nome che fa’ una serie di compiti e restituisce un valore. I frammenti di codice che hanno associato un nome e non restituisce valori sono spesso chiamati procedure. In Python non esistono procedure, perché quando il programmatore non specifica un valore di ritorno nella funzione restituisce il valore None (niente), equivalente a null in Java.
Oltre ad aiutare a programmare ed eseguire il debug dividendo il programma in parti, le funzioni consentono anche il riutilizzo del codice.
Dichiarazioni
In Python, le funzioni vengono dichiarati come segue:
		def mia_funzione(param1, param2):
		    print param1
		    print param2
Cioè, la parola chiave def seguita dal nome della funzione e gli argomenti tra parentesi tonde, separati da virgole. La definizione finisce con due punti e, in una nuova linea rientrata, possiamo scrivere il codice che compongono il blocco che deve essere eseguito dalla funzione.
Possiamo anche incontrare una stringa di testo nella prima riga del corpo funzione. Queste stringhe sono note con il nome di docstring (stringa di documentazione) e servono, come suggerisce il nome, per visualizzare la documentazione della funzione.
		def mia_funzione(param1, param2):
		    """Questa funzione consente di stampare i due valori 
		    passati come parametri"""
		    print param1
		    print param2
Questo è ciò che visualizza l’operatore ? di iPython o la funzione help del linguaggio per fornire assistenza sull’utilizzo e le utilità delle funzioni. Tutti gli oggetti possono avere docstring, non solo le funzioni, come vedremo di seguito.
Tornando alla dichiarazione di funzioni, è importante chiarire che dichiarando la funzione, tutto ciò che facciamo è quello di associare un nome al frammento di codice che costituisce la funzione, in modo da poterlo eseguire più tardi facendo riferimento al suo nome. Cioè, al momento della scrittura non si esegue la funzione. Per eseguire la funzione (l’esecuzione del codice) si dovrebbe scrivere:
		mia_funzione("Ciao", 2)
Cioè, il nome della funzione che vogliamo chiamare seguito dai valori che desideriamo passare come parametri tra parentesi tonde. L’associazione di parametri e valori passati alla funzione si fa’ normalmente da sinistra a destra: a param1 abbiamo assegnato il valore “ciao” e a param2 vale 2, mia_funzione stamperebbe ciao su una linea seguito dal 2.
Tuttavia è possibile modificare l’ordine dei parametri se indichiamo il nome del parametro da associare al valore, quando richiamamo la funzione:
		mia_funzione(param2 = 2, param1 = "Ciao")
Il numero di valori passati come parametri al richiamare la funzione deve corrispondere al numero di parametri che la funzione accetta secondo la dichiarazione della funzione. In caso contrario, Python si lamenterà:
		>>> mia_funzione("Ciao")
		Traceback (most recent call last):
		File "<stdin>", line 1, in <module>
		TypeError: mia_funzione() takes exactly 2 arguments (1 given)
È anche possibile, tuttavia, definire le funzioni con un numero variabile di argomenti, oppure è possibile assegnare valori predefiniti ai parametri nel caso non si indichi un valore per tale parametro, quando si chiama la funzione.
I valori di default per i parametri sono definiti ponendo un segno di uguale dopo il nome del parametro e quindi il valore di default:
		def stampare(testo, volte = 1):
		    print veces * texto
Nell’esempio precedente, se non indicano un valore per il secondo parametro verrà stampato una volta, la stringa passata come primo parametro:
		>>> stampare("Ciao")
		hola
… se si indica un altro valore, sarà questo il valore utilizzato:
		>>> stampare("Ciao", 2)
		CiaoCiao
Per definire funzioni con un numero variabile di argomenti dobbiamo scrivere un ultimo parametro nella dichiarazione della funzione il cui nome sarà preceduto dal segno *:
		def vari(param1, param2, *altri):
		    for val in altri:
		        print val
		vari(1, 2)
		vari(1, 2, 3)
		vari(1, 2, 3, 4)
Questa sintassi funziona creando una tupla (con il nome altri dell’esempio) che memorizza i valori di tutti i parametri aggiuntivi passati come argomento. Per la prima chiamata vari(1, 2), la tupla altri sarebbe vuota, dato che non sono stati passati altri parametri se non i due definiti per default, pertanto non stamperebbe niente. Nella seconda chiamata la tupla altri sarebbe (3), e nella terza (3, 4) che saranno stampati come da programma.
Si può anche precedere il nome del ultimo parametro con **, nel qual caso invece di una tupla si utilizzerebbe un dizionario. Le chiavi di questo dizionario sarebbero i nomi dei parametri specificati quando si chiama la funzione e i valori del dizionario sono i valori associati a questi parametri.
L’esempio seguente utilizza la funzione items dei dizionari, che restituisce una lista dei suoi elementi, per stampare i parametri contenuti nel dizionario.
		def vari(param1, param2, **altri):
		    for i in altri.items():
		        print i
		varios(1, 2, terzo = 3)
Chi conosce qualche altro linguaggio di programmazione si potrebbe chiedere se Python quando passa una variabile come argomento di una funzione lo fa’ per riferimento o per valore. Nel passaggio per riferimento ciò che viene passato come argomento è un riferimento o un puntatore alla variabile, vale a dire a un indirizzo di memoria in cui si trova il contenuto della variabile e non il suo contenuto. Nel passagio per valore, al contrario, ciò che viene passato come argomento è il valore che contiene la variabile.
La differenza tra entrambi è che nel passagio per valore le modifiche che si fanno sul parametro non si vedono al di fuori della funzione, dal momento che gli argomenti della funzione sono variabili locali alla funzione che contiene i valori indicati dalle variabili passate come argomento. In realtà ciò che viene passato alla funzione sono copie dei valori e non le variabili in sé.
Se volessimo modificare il valore di uno degli argomenti e che queste modifiche possano essere riflesse al di fuori della funzione dovremo passare il parametro per riferimento.
In C gli argomenti della funzione si passano per valore, anche se si può simulare il passaggio per riferimento usando puntatori. In Java si utilizza anche il passaggio per valore, sebbene per le variabili che sono oggetti ciò che viene passato per valore è il riferimento all’oggetto, e così sembra in realtà come un passaggio per riferimento.
Python utilizza anche il passaggio per valore di riferimenti agli oggetti, come in Java, anche se nel caso di Python, a differenza di Java, tutto è un oggetto (per l’esattezza quello che succede è che all’oggetto viene assegnato un’altra etichetta o il nome nello spazio dei nomi locale della funzione).
Tuttavia, non tutte le modifiche che facciamo ai parametri all’interno di una funzione Python si rifletteranno al di fuori di essa, giacché bisogna tener conto che ci sono oggetti immutabili in Python come le tuple, in modo che se proviamo a modificare una tupla passata come parametro ciò che accade, in realtà, è che si crea una nuova istanza, per cui le modifiche non si vedranno al di fuori della funzione.
Ecco un piccolo programma per dimostrarlo. Questo esempio utilizza il metodo append delle liste. Un metodo è semplicemente una funzione che appartiene a un oggetto, in questo caso a una lista. E append, in particolare, che serve per aggiungere un elemento a una lista.
		def f(x, y):
		    x = x + 3
		    y.append(23)
		    print x, y
		
		x = 22
		y = [22]
		f(x, y)
		print x, y
Il risultato dell’esecuzione di questo programma sarebbe
		25 [22, 23]
		22 [22, 23]
Come si vede la variabile x non conserva le modifiche una volta che lasciamo la funzione perché i numeri interi sono immutabili in Python. Tuttavia, la variabile y sì le conserva, perché le liste sono mutabili.
In breve: i valori mutevoli si comportano come passaggio per riferimento e gli immutabili come passaggio per valore.
Si conclude così tutte le questioni relative ai parametri delle funzione. Vediamo infine come restituire i valori, dove si utilizza la parola chiave return:
		def sommare(x, y):
		    return x + y
		print sommare(3, 2)
Come si vede questa semplice funzione non fa altro che sommare i valori passati come parametri e restituisce il risultato come valore di ritorno.
Possiamo passare anche più valori con return.
		def f(x, y):
		    return x * 2, y * 2
		a, b = f(1, 2)
Tuttavia, questo non significa che le funzioni di Python possono restituire più valori, ciò che accade è che Python crea una tupla al volo i cui elementi sono i valori da restituire, e questa è l’unica variabile che viene restituita.


Similari
Fondamentali di jQuery
232% JQuery
[nextpage title=”Benvenuti”] jQuery stà diventando rapidamente uno strumento che ogni sviluppatore web di interfacce dovrebbe conoscere. Lo scopo di questo libro è di fornire una panoramica della biblioteca, in modo che qu…
Guida allo Zend Framework
106% Zend
Zend Framework è un framework open source per PHP. Zend Framework separa la logica e le azioni usando il pattern MVC (Model View Controller). Cosa è lo Zend Framework? Framework per la costruzione di siti web più veloci e …
Modi di fare e di non fare in Python
89% Python
Questo documento può essere considerato un compagno del tutorial di Python. Viene illustrato come utilizzare Python, e quasi ancora più importante, come non usare Python. [expand title=”Costrutti del linguaggio che non dov…
Funzioni popolari per gestire le stringhe
71% Php
PHP ha una vasta scelta di funzioni integrate per la gestione delle stringhe che permettono di manipolarle facilmente in quasi ogni modo possibile. Tuttavia, imparare tutte queste funzioni, ricordando quello che fanno e qu…
Introduzione al PHP
43% Php
Scopri ed esplora la programmazione di scripting server side con il linguaggio PHP. Questo post è rivolto a persone che sono nuovi alla programmazione. Non è adatto a persone che già hanno competenze di programmazione di b…