LangageVersions

[wiki: Python 2 vs 3]

PageOutline

#!comment''
CLASSES NEW STYLE ?

METTRE A JOUR AVEC LES INFOS DU MOOC

Instructions et fonctions prédéfinies

Print

En Python 2, print était une instruction.

#!python


titre = 'exemple'
ligne = '='*len(titre)
print titre, '\n', ligne


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
exemple


=

</pre>


Dans l’exemple ci-dessous, on n’appelait pas une fonction print(), mais on appelait l’instruction print qui est suivie d’une valeur entre parenthèses.

#!python


print('exemple')


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
exemple
</pre>

Dans l’exemple ci-dessous, on n’appelait pas une fonction print(), mais on appelait l’instruction print qui est suivie d’un tuple de trois éléments.

#!python


titre = 'exemple'
ligne = '='*len(titre)
print(titre,'\n',ligne)


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
('exemple', '\n', '=======')
</pre>

En Python 3, print() est une fonction.

#!python


titre = 'exemple'
ligne = '='*len(titre)
print(titre,ligne,sep='\n')


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
exemple


=

</pre>


Input

En Python 2, input() interprétait le texte saisi, raw_input() ne l’interprétait pas.

En Python 3, input() n’interprète pas le texte saisi (il faut faire eval(input())).

Iteration

La méthode d’itération s’appellait next() en Python 2, et devient next() en Python 3.

Range

En Python 2, l’usage de range() était découragé en cas de grandes valeurs, au profit de xrange(), qui ne renvoie pas une liste préconstruite de tous les entiers demandés, mais les prépare et les fournit un par un, au fur et à mesure du besoin.

En Python3, range() reprend l’ancien comportement de xrange().

Map

En Python 2, la fonction map() renvoie une liste, directement imprimable.

En Python3, la fonction map() renvoie un itérateur, qu’il faut parcourir ou transformer en liste pour pouvoir l’imprimer.

Chaines de caractères

Types de caractères

En Python 2, les chaînes étaient par défaut des séquences de caractères ASCII. On pouvait explicitement obtenir une chaîne unicode à l’aide du préfixe « u » : s4 = u"chaine unicode".

En Python 3, les chaînes deviennent des séquences de caractères unicode. On peut explicitement obtenir une chaine d’octets (type bytes) à l’aide du préfixe « b » : s4 = b"chaine unicode".

Méthodes et fonctions

Avant les dernières versions de Python 2, on manipulait les chaînes à l’aide des fonctions du module string. A présent, on utilise les méthodes du type str, y compris sur des littéraux :

>>> elements = 'A/B/C'.split('/')
>>> print('|'.join(elements))
A|B|C

Formatage

L’opérateur historique pour le formattage des chaines est le %, basé sur une syntax inspirée du « printf » du langage C :

>>> mois = ['Janvier','Fevrier','Mars','Avril','Mai','Juin',
            'Juillet','Aout','Septembre','Octobre','Novembre','Decembre']
>>> print "Vous avez choisi %s" % mois[3]
Vous avez choisi Avril

Cependant, il est appelé à disparaitre, au profit de la méthode str.format()

>>> mois = ['Janvier','Fevrier','Mars','Avril','Mai','Juin',
            'Juillet','Aout','Septembre','Octobre','Novembre','Decembre']
>>> print("Vous avez choisi {0}".format(mois[3]))
Vous avez choisi Avril

Calcul numerique

Types entiers

En Python 2, nous disposions de deux types :

  • int (équivalent d’un long du C) : 1234, 045, 0xFC
  • long (sans limite de taille) : 999L

Les objets glissent automatiquement du type int à long lorsqu’ils deviennent trop grands. On peut mélanger entiers courts et longs dans des opérations, le résultat étant systématiquement un long.

En Python 3, il n’y plus qu’un seul type int combinant précision illimitée et représentation interne optimisée.

Division

En Python 2, en présence d’entiers, / appliquait un quotient entier et retournait un entier, à la façon de //.

>>> 2/3
0
>>> 2./3.
0.6666…
>>> 6/2
3
>>> 6./2.
3.0

En Python 3, / applique toujours une division classique et retourne toujours un nombre flottant.

>>> 2/3
0.6666…
>>> 2./3.
0.6666…
>>> 6/2
3.0
>>> 6./2.
3.0

Importation de module

En Python 2, les produits à importer sont recherchés en priorité dans le répertoire/package courant :

#!python
# fichier pkg/init.py
import mod
#!python
# fichier pkg/mod.py
print name
#!python
# fichier mod.py
print name
>>> import pkg
pkg.mod

En Python 3, le répertoire/package courant est ignoré :

#!python
# fichier pkg/init.py
import mod
#!python
# fichier pkg/mod.py
print(name)
#!python
# fichier mod.py
print(name)
>>> import pkg
mod

On peut obtenir un import « relatif » en Python 3 à l’aide de l’instruction from ..

#!python
# fichier pkg/init.py
from . import mod
#!python
# fichier pkg/mod.py
print(name)
#!python
# fichier mod.py
print(name)
>>> import pkg
pkg.mod

On peut également obtenir l’import « global » de Python3 en Python 2 grâce à la commande from !future! import absolute_import.

  • En python 2
#!python
# fichier pkg/init.py
from future import absolute_import
import mod
#!python
# fichier pkg/mod.py
print name
#!python
# fichier mod.py
print name
>>> import pkg
mod

ATTENTION : cette problématique n’est valide qu’au sein des packages. Dans un script,
ou dans les modules de même niveau qui ne sont pas intégrés au sein de packages, il
faut continuer d’utiliser des importations absolues (les importations relatives
ne fonctionnent pas).

#!html
<br clear=right>

Divers

  • Seul != est autorisé pour exprimer l’inégalité (et <> ne l’est plus).
  • Les classes suivent par défaut le « nouveau style ».
  • Les exceptions maisons doivent être des classes.
#!comment


  • Except et finally ne peuvent être mélangés qu'à partir de 2.5
  • With/as à partir de 2.6
  • exceptions maisons de type classes plutot que string à partir de 2.5 ?

#!html
<br clear=right>

Migrer de Python 2 à 3

  • Pourquoi rester en Python 2 ? Pour profiter des multiples bibliothèques disponibles.
  • Pourquoi migrer en Python 3 ? Pour profiter de ses simplifications et de ses optimisations :
  • fusion des types ‘int’ et ‘long’
  • a/b est la vraie division par défaut.
  • exec et print deviennent des fonctions.
  • itérateurs et vues plutôt que des listes (range(), map(), filter(), zip(), dict.keys(), dict.items(), dict.values()).
  • les chaînes sont en Unicode par défaut, ‘bytes’ remplace l’ancien type ‘str’
  • disparitions : `x`, l’opérateur <>, la méthode find() des chaînes, les fonctions apply(), buffer(), callable(), reduce()…
  • None et as deviennent des mots clé.
  • A noter : une commande (2to3) et une bibliothèque (lib2to3) sont supposées aider les programmeurs à migrer leur code.
  • A essayer dès 2.X
  • Utiliser les méthodes du type str au lieu du module string
  • A répéter dans tous vos fichiers :
  • from !future! import print_function
  • from !future! import division (2/3 retourne un float)
  • from !future! import absolute_import

References

#!comment


Pour mémoire, un exemple de mise en page avec du bleu à gauche et du jaune à droite en vis à vis.

{{{
#!div style="float:left;width:48%"

{{{
#!python

>>> titre = 'exemple'
>>> ligne = '='*len(titre)
>>> print(titre,ligne,sep='\n')
exemple
=======


}}}

#!div style="float:right;width:48%"


{{{
#!html
<pre style="margin-right:20px;border: 1px solid palegoldenrod;padding:4px;background-color:lightyellow">
>>> titre = 'exemple'
>>> ligne = '='*len(titre)
>>> print titre, '\n', ligne
exemple

=

</pre>


}}}

#!html
<br clear=right>

}}}