Différences principales python3 / python2

P

YTHON 2 ne sera plus supporté à partir du premier janvier 2020, il est donc temps de passer à python3 si ce n'est déjà fait. Si vous retrouvez d'anciens scripts en python2, lisez cette page pour connaître les différences principales.

Page remaniée au 2019.08.15

Mots réservés - Fonctions - UTF-8 - Chaînes - Nombres - Collections

Mots réservés

Les mots réservés en python3, qui ne peuvent être utilisés comme nom de variable ou de fonction, sont (ceux en rouge existaient en python2 et sont supprimés): and - as - assert - break - class - continue - def - del - elif - else - exec - except - finally - for - from - global - if - import - is - lambda - not - or - pass - print - raise - return - try - while - with - yield

Remarques: with et as avaient déjà été ajoutés à python 2.6

exec()

En python3, la fonction interne exec() remplace le «mot réservé» exec de python2:

>>> exec("from math import sin,pi; print(sin(pi/4))")
0.7071067811865475

Remarque: en python 2.7, exec et exec() sont valables et synonymes.

print()

En python3, la fonction interne print() remplace le «mot réservé» print de python2:

print("Eggs & spam") remplace print "Eggs & spam"

print("J'ai", 23, "ans", sep=" - ") permet de remplacer l'espace (séparateur par défaut) par une chaîne
print("Eggs", end=" ; ") remplace le saut de ligne par une chaîne. Attention: une suite de print(chaine,end="") ne sera affichée qu'à partir du premier print() contenant un saut de ligne. Ne convient pas pour afficher une barre de progression horizontale.

Note: en Python 3.0 et 3.1, print("%,d" %(1234)) permettait d'afficher la virgule séparatrice de milliers, et %b permettait la sortie d'un entier en binaire. Il est possible néanmoins d'obtenir ce format avec:

print(format(123,"#b"))

En python 2.6, il est possible d'utiliser print() avec parenthèses à partir de grâce à from __future__ import print_function (sur la première ligne du script ne commençant pas par '#').

Fonctions internes supprimées

from __future__

from __future__ import ... était nécessaire en début de script de python2.x pour bénéficier d'évolutions réservées à python3. Elles ne devraient plus servir à grand-chose, puisque python3 est le futur depuis longtemps. Peut-être ce type d'import sera-t-il réintroduit lors de la sortie de python4...

execfile()

execfile() n'existe plus en python3. Il pourrait être remplacé par (non testé):

exec(open(nomdefichier).read())

file()

open() est l'unique manière d'ouvrir un fichier en python3, son équivalent file() en python 2 n'existe plus.

input() remplace raw_input(), supprimé

Python2 faisait une différence entre input() et raw_input(). Le premier évaluait une saisie, calculant une opération ou exécutant une commande, le second envisageant l'entrée comme une simple chaîne. En python3, input() permet la simple saisie et remplace raw_input() de python2, supprimé. Pour évaluer une saisie, utiliser eval():

>>> print(eval(input("Entrer une division: ")))
Entrer une division: 3/4
0.75

reduce() doit être importé

En Python 3, la fonction reduce() doit être importée du module functools.

>>> import functools
>>> functools.reduce(lambda x,y:x*y,range(1,7))
720

Il s'agit d'une factorielle, tous les nombres issus de range(1,7) étant multipliés l'un après l'autre. Malgré le fait que le Guido Van Rossum se repent d'avoir introduit la fonction lambda, cele-ci n'a pas encore disparu.

UTF-8 est la norme

En python3, les chaînes sont par défaut en UTF-8, ce qui signifie que

# -*- coding: utf-8 -*-

n'est plus nécessaire en début de script (n'oubliez pas de paramétrer la console en UTF-8).

En python3, les noms de variable et de fonction peuvent contenir des lettres accentuées. Cette nouvelle utilisation n'est pas conseillée dans le cadre d'un projet international, car même si l'UTF8 permet un codage universel de ces caractères, tous les claviers n'ont pas les mêmes facilités à produire toutes les lettres accentuées. Pour vous en convaincre, tentez š, æ, å... avec un clavier azerty... En python2, les lettres accentuées sont interdites dans les noms de variable ou de fonction.

Pour tout autre encodage que l'UTF-8, il faut le préciser avec (par exemple)

# -*- coding: latin-1 -*-

Chaînes

Ce passage en UTF-8 implique des changements importants dans la manipulation des chaînes: pour la chaîne ch="côté", ch[3] vaut le caractère é (avec python2, cela dépendait de l'encodage). C'est extrêmement utile lors de décomposition de chaînes.

#! /usr/bin/python3

chaine="côté"
print(len(chaine)) # la réponse est 4
print(chaine[3])   # la réponse est 'é'
#! /usr/bin/python2
# -*- coding: utf-8 -*-

chaine="côté"
print(len(chaine)) # la réponse est 6: 'ô' et 'é' valent chacun deux octets
print(chaine[3])   # la réponse est 't'

decode() n'existe plus en python3.

Note: la différence de poids de fichier texte en français entre les encodages iso-8859-15 et UTF-8 d'un même texte est assez minime, environ 5% de plus pour le second pour un texte français. Ce n'est pas le cas si vous utilisez des textes en arabe ou en grec (deux octets par lettre en UTF-8 contre un octet en iso-8859-7 ou iso-8859-6) ou en idéogrammes (trois octets, contre deux dans les encodages spécifiques aux langues asiatiques).

cmp(x,y), qui renvoyait -1 si x<y, +1 si x>y et 0 si x==y, est supprimée en python3. Si vous avez vraiment besoin de cette fonction, il est possible de l'écrire vous-même:

def cmp(v1,v2):
  return (v1>v2) - (v1<v2)

Nombres

Le suffixe L et la fonction long() de python 2 sont abandonnés, les entiers sont tous illimités en python3.

En python3, != est le seul opérateur de test d'inégalité: <>, déjà déprécié en python 2, est supprimé en python3.

En python3, la chaîne octale commence nécessairement par 0o43 ou 0O43 (le chiffre 'zéro' et la lettre 'o', minuscule ou majuscule). 077 seulement préfixé du zéro n'est plus reconnu et engendre l'erreur invalid token.

cmp(x,y), qui renvoyait -1 si x<y, +1 si x>y et 0 si x==y, est supprimée en python3. Si vous avez vraiment besoin de cette fonction, il est possible de l'écrire vous-même:

def cmp(v1,v2):
  return (v1>v2) - (v1<v2)

Divisions

En python3, la division / n'est plus entière: 7/4 vaut 1.75 . La division entière est continue à être codée //.

>>> 7//4
1
>>> -7//4
-2

#! /usr/bin/python -Qnew permettait d'utiliser / pour la division non entière. -Qnew est inutile et interdit en python 3.

round(n) limite l'affichage du nombre à la décimale demandée

>>> round(3.14159,2)
3.14

Jusqu'à python 2.6, il pouvait y subsister une imprécision: round(3.14159,2) donnait 3.1400000000000001.

Collections

cmp(x,y), qui renvoyait -1 si x<y, +1 si x>y et 0 si x==y, est supprimée en python3.

De plus, les opérateurs < et > ne fonctionnent plus en python3 pour comparer les collections.

Python 3 connaît une nouvelle forme de dictionnaire: OrderedDict, qui conserve la mémoire de l'ordre de ses éléments.

En python2, beaucoup de réponses de fonctions internes ou de méthodes renvoyaient une liste []. Elles sont maintenant remplacées par des itérateurs spécifiques. Par exemple,

Cela signifie que le référencement par index xx[n] et des méthodes telles que .pop() n'y sont plus applicables ; il reste possible de itérer directement:

>>> for i in map(ord,'python'):
...  print(i)
...
112
121
116
104
111
110

Il est également permis d'en faire une liste à partir d'un de ces objets:

listecles=list(Mon_Dico.keys())