Différences principales python3 / python2

P

YTHON 2 n'est plus supporté depuis le 1er janvier 2020, veuillez vous en souvenir si vous commencez un nouveau développement. Si vous retrouvez d'anciens scripts en python2, cette page devrait vous aider à en adapter le code.

Réécriture (2019.12.28) de la page introduidant les nouveautés apportées par python3

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

Mots réservés

Certains mots réservés en python2 ne le sont plus en python3: exec - print

python2.6 avait déjà ajouté les mots réservés with - as

exec()

Le mot réservé exec est remplacé par la fonction interne exec():

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

Remarque: exec et exec() étaient synonymes en python 2.7.

print()

Le «mot réservé» print de python2 est remplacé par la fonction interne print():

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.

Remarque: il était déjà possible d'utiliser print() en python 2.6 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. Peut-être ce type d'import sera-t-il réintroduit à l'approche de la sortie de python4...

execfile()

La fonction interne execfile() de python peut être remplacée par:

exec(open(nomdefichier).read())

file()

L'ouverture des fichier par python2 connaissait également la fonction file(), open() est maintenant l'unique manière d'ouvrir un fichier en python3.

input() remplace raw_input(), supprimé

En python2, input() évaluait une saisie et raw_input() considérait l'entrée comme une simple chaîne. En python3, raw_input() de python2 est remplacé par input() pour la simple saisie. Pour évaluer la chaîne saisie, utiliser eval():

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

reduce() doit être importé

La fonction interne reduce() de python doit en python3 ê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, celle-ci n'a pas encore disparu.

Chaînes

UTF-8 est maintenant la norme

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

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

n'est plus nécessaire en début de script. N'oubliez pas de sauvegarder vos scripts en UTF-8 et de paramétrer la console en ce sens.

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

# -*- coding: latin-9 -*-

Note: la différence de poids de fichier texte en français entre les encodages iso-8859-15 (latin-9) 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 ou kanas (trois octets, contre deux dans les encodages spécifiques aux langues asiatiques).

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 é. 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.

Le type 'bytes' (octet)

Par ailleurs, il était possible en python2 de réaliser une chaîne d'octets de chr(0) à chr(255) pour sauvegarder des données «binaires», ce n'est plus possible en python3, où chr(255) n'est plus un octet mais le caractère unicode 255, soit le "ÿ", qu'UTF-8 code en deux octets.

Une façon d'assembler des octets est de passer par le type 'bytes', déjà disponible en python2.6. Cela peut se faire de cette façon:

Une autre façon est de construire le bytearray petit à petit:

>>> ba=b""; ba+=b"A"; ba+=b"\x217"; ba
b'A!7'

Attention: b"\217" représente deux bytes: le premier \x21 (b'!') et le second est l'ASCII du caractère 7.

Nombres

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

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

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 python3.

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 dictionnaires.

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())