Sebbene il focus di questa guida sia stato centrato su Python 3, ci sono ancora molti sviluppatori che, per necessità o comodità, continuano ad utilizzare le versioni 2.x di questo linguaggio di programmazione. Purtroppo, le versioni dei due linguaggi presentano alcune differenze che, sebbene apparentemente semplici, comportano la necessità di scrivere codice specificamente pensato per l'una o l'altra versione.
Esiste però la possibilità, per gli sviluppatori che utilizzano Python 2, di sfruttare alcune utili funzionalità introdotte con Python 3. Tale possibilità si basa sull'uso dei future statement, ovvero del modulo fittizio __future__
. In questa lezione vedremo come utilizzarlo, facendo riferimento alla versione 2.7 di Python.
Utilizzare print come funzione
Un primo esempio che ci permette di capire l'utilità del modulo __future__
consiste nell'utilizzare la funzione print
, che su Python 2.x è invece definita come statement:
print "Ciao!" #sintassi supportata solo su Python 2.x
Volendo "avvicinare" un po' di più la sintassi a quella di Python 3, possiamo sfruttare il modulo __future__
come segue:
from __future__ import print_function
print("Ciao!") #sintassi di Python 3, riportata anche su Python 2.x
Come si vede, è basato una semplice import
per cambiare (di fatto) la sintassi di Python 2.x. È importante notare che questa sintassi non ha soltanto definito una nuova funzione print
, ma ha anche eliminato lo statement print. Ad esempio, il codice seguente causerebbe un errore di sintassi:
from __future__ import print_function
print "Ciao!" #errore di sintassi
Sebbene la sintassi utilizzata coincida con quella che permette di includere un modulo, quello che abbiamo fatto è, in realtà, l'utilizzo di un future statement. Si tratta di una direttiva del compilatore che forza l'interprete Python ad interpretare le righe che includono (in questo caso) la funzione print
in modo da supportare le versioni future del linguaggio. Si noti che, proprio per questo motivo, i future statemente devono essere necessariamente posti all'inizio di ogni file in cui vengono utilizzati.
Divisioni
Un'altra semplice funzionalità che può tornare molto utile agli sviluppatori di Python 2.x è la gestione delle divisioni tra interi. Su Python 2.x, infatti, l'operatore /
funziona in modo analogo a linguaggi come C, C++ e Java, in cui il tipo degli operandi può cambiare radicalmente il risultato della divisione. Facciamo un esempio:
3 / 2 #su Python 2.x, il risultato è 1. Su Python 3, il risultato è 1.5
3.0 / 2 #sia su Python 2.x che su Python 3, il risultato è 1.5
3 // 2 #sia su Python 2.x che su Python 3, il risultato è 1
L'esempio precedente mostra come Python 3 differenzi il risultato dell'operazione grazie all'introduzione dell'operatore //
, che effettua esplicitamente l'arrotondamento per difetto sul risultato della divisione. Su Python 2.x, invece, non c'è differenza tra /
e //
. Per importare questa funzionalità su Python 3, possiamo sfruttare ancora una volta un future statement:
from __future__ import division
3 / 2 #risultato: 1.5
3 // 2 #risultato: 1
Altre funzionalità
Oltre alle due funzionalità relative alla funzione print
ed alle divisioni tra interi, i future statements permettono di importare molte altre caratteristiche della versione 3 del linguaggio Python anche su Python 2.x. Una di queste è il costrutto with
, già visto nella lezione sui file, che può essere importato come segue:
from __future__ import with_statement
with open('text.txt', 'r') as f: #sintassi di Python 3 utilizzata su Python 2.x
print f.read() #sintassi standard di Python 2.x
Altre funzionalità che possono essere incorporate tramite i future statement sono identificate dalle seguenti stringhe (che devono seguire la solita sintassi from __future__ import
):
nested_scopes
generators
absolute_import
unicode_literals
Per maggiori dettagli, è comunque possibile consultare la documentazione ufficiale.
Infine, è bene segnalare la possibilità di installare il modulo aggiuntivo python-future (che può essere ottenuto mediante pip
), che implementa alcune ulteriori funzionalità, al fine di facilitare il porting del codice da Python 2.x a Python 3, nonchè di garantire la retrocompatibilità del codice Python 3 su Python 2.x. Ulteriori informazioni possono essere reperite sul sito ufficiale del progetto.