De python2 à python3 : convertir un script et principales différences
PYTHON2 n’est plus supporté depuis le 1er janvier 2020, bien qu’il puisse encore être installé sur votre système (par exemple python2.7 avec Debian 11 Bullseye, aout 2021). Tout nouveau développement doit donc se faire en python3. Cette page devrait vous aider à adapter d’anciens scripts écrits en python2 ; voyez ici pour tkinter.
2025.05.17 – passage à l’orthographe réformée de 1990
Liens internes
apply() · as · bytes · chaines · cmp() · comparaisons · decode() · dictionnaires · divisions / et // · encodage · ensembles · exec · execfile() · False · file() · filter() · from __future__ · has_key() · différence != et <> · input() · intern() · .isalpha() · .items() · itérateurs · .keys() · listes · long() · map() · max() · min() · nombres · octal · print · print >> · raise · range() · raw_input() · reduce() · round() · set() · True · type() · unichr() · unicode() · .values() · variables · with · xrange()
Application 2to3
Il existe une application (non python) appelée 2to3, disponible notamment sur Debian, et qui transforme les scripts python2 en scripts python3. Elle semble assez difficile à utiliser, s’arrêtant déjà sur le fait que l’encodage du script est en iso-8859-15 (latin9) alors que l’application s’attend à de l’UTF-8. Il faut charger le script avec un éditeur de texte et le «sauvegarder sous» en spécifiant l’encodage UTF-8.
Ce problème résolu, l’application retourne :
ModuleNotFoundError: No module named 'lib2to3'.
Et c’est bien dommage. Cette application était donc basée sur le module lib2to3, qui semble abandonné depuis python3.13.
Transformation «à la main»
Si vous voulez transformer vous-même un ancien script python2 en python3 «à la main», il faut d’abord changer l’entête (cas de UNIX) :
#! /usr/bin/python -Qnew # -*- encoding: latin9 -*- from __future__ import print_function
en
#! /usr/bin/python3
L’encodage du script (et de la console) devra alors être en UTF-8, sauf si l’on garde par exemple l’une des lignes suivantes :
# -*- encoding: latin1 -*- # -*- encoding: cp1252 -*- # -*- encoding: latin9 -*-
Il faut ensuite
- sauvegarder le script dans l’encodage choisi (sauvegarder sous…)
- vérifier ou paramétrer l’encodage de la console pour qu’il corresponde à celui du script. Exemples de problème :
- Å“ est le couple d’octets codant le caractère œ codé en UTF-8 que la console en codage octet (win1252, latin1, latin9…) interprète en deux caractères distincts
- � est un octet qui code en un octet un caractère accentué en win1252, latin1, latin9…, que la console en UTF-8 ne peut interpréter
Pour plus d'informations, voir ci-dessous.
unichr() est supprimé
Le fait que les chaines sont traitées en interne en UTF-8 est un changement majeur en python3.
- unichr() doit être remplacé par chr() qui vaut pour tous les «points de code», bien au delà de 255, voir la page des caractères.
- les fonctions unicode(), les objets u"", le type 'unicode' et unichr() n’existent plus en python3
Ensuite modifier :
- print expression en print(expression)
- input() en eval(input())
- raw_input() en input()
- file() en open() (les deux coexistent en python2)
- execfile() en exec(open("myfile").read())
- …puis lancer le script dans une console, guetter les erreurs et les corriger.
Note : en python2, print() devenait obligatoire avec la directive from __future__ import print_function
Pour plus d’informations, voir la page consacrée à python3.
Mots réservés
Les expressions suivantes ne peuvent pas servir de nom de variable ou de fonction :
and · as · assert · break · class · continue · def · del · elif · else · except · exec · False · finally · for · from · global · if · import · in · is · lambda · None · not · or · pass · print · raise · return · True · try · while · with · yield
True et False n’étaient pas réservés en python2.7 (ce qui fait qu’il pouvait y coexister une variable ou une fonction du même nom) mais le deviennent en python3.
with et as ont été ajoutés en python2.6 et sont conservés en python3
exec et print étaient réservés en python2 mais ne le sont plus en python3. print() était déjà possible en python2.5 avec from __future__ import print_function (première ligne du script ne commençant pas par ’#’) ; exec() et print() coexistaient en python2.6 avec print et exec.
Fonctions
exec() remplace le mot-clé exec
Le mot réservé exec est remplacé par la fonction intégrée exec() :
>>> exec("from math import sin, pi ; print(sin(pi /4))") 0.7071067811865475
Remarque : exec et exec() sont synonymes en python2.7.
Le «mot réservé» print de python2 est remplacé par la fonction print() en python3 :
Attention : Les appels successifs à print(chaine, end="") n’affichent pas de nouvelle ligne, sauf quand un print() avec saut de ligne est rencontré, ou si flush =True est spécifié ; cela permet par exemple de réaliser une barre de progression :
Pour un affichage plus élaboré sur la console, voir le module curses.
Remarque : il est déjà possible d’utiliser print() depuis python2.6 grâce à from __future__ import print_function (sur la première ligne du script ne commençant pas par ’#’). Cela a permis de préparer python2 à adopter la syntaxe python3 : l'instruction print est devenue la fonction print().
Depuis python2.7, il était possible de remplir une chaine lacunaire avec .format() sans les numéros d’ordre :
Depuis python3.4, une chaine de formatage f"{data:format}" est disponible :
from __future__ est nécessaire en début de script de python2.x pour bénéficier d’évolutions de python3 et préparer la transition.
Dépréciée en python2, cette fonction y est déjà remplaçable par l’utilisation de * et ** pour la réception des éléments d’une séquence (liste, tuple ou chaine) ou d’un dictionnaire. Dans l’utilisation d’ apply(), le nombre d’éléments envoyés doit être égal au nombre de variables réceptrices, et les noms de clés doivent aux noms de variables :
donne :
Python3 n’accepte plus que ce passage de groupes de paramètres :
…ce qui renvoie :
Une suite d’affectations sera reçue comme un dictionnaire si la variable de réception est préfixée par ** :
Il est possible de composer les deux, les valeurs passées en paramètres doivent alors précéder les affectations.
Il est facile de recréer la fonction cmp() pour comparer des nombres (voir la discussion sur cette page) :
En python2, cmp(x, y) renvoyait -1 si x < y, +1 si x > y et 0 si x == y ; cmp(x, y) acceptait de comparer des valeurs de classes / types différents.
Plusieurs changements importants en python3, qui devient très difficile concernant les hiérarchies.
En python2, les réponses aux comparaisons d’objets de classes différentes sont stéréotypées (mais les complexes refusent les relations d’ordre (<, >, <=, >) avec des entiers, «réels» ou complexes) :
En python3, seules les comparaisons entre objets de même classe sont permises, mais pour les ensembles, < signifie «être inclus» et > «contenir». Les complexes continuent à ne pas vouloir être comparés entre eux, sauf avec == et !=.
Python2 admettait la comparaison de dictionnaires, par paire clé/valeur et selon leurs longueurs :
Les comparaisons de dictionnaires sont interdites :
En python2, les clés, d’abord mises en ordre alphabétiques, étaient comparées.
Il en résulte que pour que deux listes soient comparables, il faut que les valeurs soient de même classe / type à chaque rang, et ne pas contenir de dictionnaires :
Notes : les comparateurs == et != fonctionnent dans tous les cas.
Il est quand même possible de mettre de l’ordre dans les données d’un dictionnaire si les clés sont toutes de même classe / type :
La fonction execfile() de python2 peut être remplacée par :
ou mieux :
Si python2 connaissait également la fonction file(), open() est l’unique manière d’ouvrir un fichier en python3.
Toutes les versions de python3 connaissent également une structure pour l’ouverture d’un fichier :
...même si open(fichier.txt", "w").write("montexte") est encore plus court. L'intérêt de
est que le fichier est correctement refermé même en cas d'erreur.
Important : python2 chargeait un fichier-texte en acceptant les deux octets possibles pour les fins de ligne (Windows : \r\n (octets 13 et 10), MacOS9 :\r (octet 13)). Python3 convertit les fins de ligne de tous les systèmes en caractères \n (octet 10) et, supposera-t-on, les convertit automatique dans les fins de lignes du système-hôte (je n'ai ni Mac ni Windows sous la main).
En python2, une façon simple de rediriger les sorties print vers un fichier-texte sans utiliser le module sys :
C’est tout aussi simple en python3 :
(fichier refermé à la fin de la structure), ou encore :
L’intérêt (relatif) de la méthode avec fd.close() est peut-être d’ouvrir un fichier en écriture ou en ajout en début de script, d’y ajouter des données au cours du script et de le fermer à la fin. Mais il est possible de stocker ces données dans une variable et de ne la sauvegarder qu’à la fin.
En python2, raw_input() servait à saisir une chaine tandis que input() en évaluait la saisie :
En python3, raw_input() est supprimé et toute saisie de chaine se fait avec input(). Pour évaluer la chaine saisie, on doit utiliser eval() :
Attention : eval(input()) permet l'introduction et l'exécution de code malsain.
En Python2, la fonction var =intern("") inscrivait une chaine parmi les variables du système, censées être plus rapidement mobilisables (aucun test de ma part n’a été concluant). En Python3, il faut utiliser sys.intern().
Cette technique permettrait de gagner du temps dans la comparaison de chaines, immuables.
La fonction intégrée reduce() de python2 doit en python3 être importée du module functools.
Il s’agit d’une factorielle, tous les nombres issus de range(1, 7) étant multipliés l’un après l’autre. Bien que que Guido Van Rossum se repente d’avoir introduit la fonction lambda, celle-ci n’a pas encore disparu.
Avant la version python2.4, les entiers étaient limités de -2 147 483 648 à +2 147 483 647. Pour permettre une variable représentant un entier illimité, il fallait préalablement utiliser long(), le nombre produit étant terminés par un L. Depuis la version 2.4, il n’y a plus de problèmes lorsqu’un entier dépasse les limites : si un résultat se situe en dehors de cet intervalle, L suit automatiquement le nombre : var =100000 *100000 équivaut à 10000000000L. Le L est supprimé en python3, tous les entiers étant illimités.
En python2, type(0L) retournait <type 'long'> entier illimité
En python3, les entiers sont tous illimités et sont des objets <class 'int'>.
En python2, a, b =coerce(a, b) ajustait les variables numériques dans la classe (ou type) le plus englobant, avec la hiérarchie complexe > float > long > int
Cette fonction a été abandonnée en Python 3, probablement en raison de la suppression des entiers longs et de l’impossibilité de comparer des nombres complexes avec d’autres types. De toute façon, la comparaison entre entiers et flottants fonctionne sans problème.
Déjà déprécié en python2, <> est supprimé en python3, où != est le seul opérateur testant l’inégalité.
En python2, une chaine octale commence par un zéro 0 (06.5 est néanmoins interprété comme le réel 6.5 en base 10), mais python2.6 et 2.7 acceptent la notation 0o43.
En python3, la chaine octale commence nécessairement par 0o ou 0O (le chiffre ’zéro’ et la lettre ’o’, minuscule ou majuscule). L’expression 077 (seulement préfixée avec zéro) n’est plus reconnue comme nombre octal et engendre l’erreur invalid token.
En python2, la division de deux entiers était entière : 7 /4 retournait 1. Un point après un nombre forçait Python à considérer la réponse comme décimale :
Il était possible en python2 d’utiliser / comme diviseur non entier en mentionnant en début de programme (future est entouré de part et d’autre de deux "soulignés") :
Une autre façon était une déclaration en fin de première ligne
En python3, la division / retourne un «réel» dans tous les cas :
La division entière continue à être codée //. Attention cependant aux résultats négatifs :
Certaines versions de python2 retournaient parfois un résultat imprécis pour round(), mais toujours sous forme «réelle» même avec python2.7 :
Python3 limite l’affichage d’un nombre à la décimale demandée de façon précise et sous forme d’entier le cas échéant :
Python2 arrondissait toujours le chiffre .5 par excès :
Python3 arrondit le .5 vers le nombre pair le plus proche :
Pour une explication, voir round() sur la page python3.
En Python 3, l'encodage par défaut est UTF-8, norme qui permet de représenter tous les caractères du monde, des lettres accentuées aux idéogrammes et émoticônes.
En Python 2, l’encodage par défaut était ASCII, limité aux lettres non accentuées, chiffres, ponctuation, opérateurs usuels et quelques caractères spéciaux :
Le lancement d’un script comportant une lettre accentuée :
retournait le message d’erreur suivant :
Les francophones utilisaient donc souvent une directive d’encodage permettant les lettres accentuées courantes :
pour obtenir :
Pour se limiter au français, on avait le choix entre les synonymes latin, latin1, latin-1 ou iso8859-1, le jeu de caractère légèrement amélioré latin9 ou iso8859-15 et le jeu de caractère Windows cp1252 ou windows-1252, qui utilise une trentaine de caractères supplémentaires, la plupart typographiques. Voyez cette page pour les nuances.
Important ! Il est nécessaire de faire correspondre l'encodage du script, de la console et de la directive coding (voir point suivant).
La norme Unicode a pour objectif de répertorier tous les caractères possibles de tous les alphabets, syllabaires, idéogrammes, symboles, ponctuations typographiques, dingbats et de plus en plus d’émoticones, en utilisant généralement l’UTF-8 qui code ces caractères en une suite d’un à quatre octets, un seul pour les caractères ASCII, deux pour chaque lettre accentuée et beaucoup d’alphabets non-européens, trois pour les idéogrammes, les symboles mathématiques et les signes typographiques spécialisés et quatre pour les émoticones, les hiéroglyphes et signes cunéiformes.
Il serait fastidieux de passer tous les cas en revue d’encodages croisés entre paramétrage de la console, directive d’encodage en début de script et type de sauvegarde, mais il est possible de relever deux incompatibilités habituelles :
Conclusion : toujours bien veiller à ce que la directive d’encodage, la sauvegarde d’un script et le paramétrage de la console soient bien accordés.
Il était possible de préciser l’encodage UTF-8 en python2, à condition de sauvegarder le script et de paramétrer la console dans ce même encodage:
Sans encodage spécifié, un script python2 fonctionne uniquement s’il ne contient que des caractères ASCII. Il fonctionne alors directement en n'importe quel autre encodage, et dont l'UTF-8, encodage par défaut de python3, il n'y a donc rien à préciser. Si un autre encodage est utilisé (iso8859-15 ou cp1252), il devait être précisé en python2, il suffit de garder le même encodage en python3Pour passer en UTF-8, enlever la directive d'encodage et sauvegarder le script en UTF-8 («sauver sous»).
Note : la différence de poids de fichier texte en français entre les encodages latins (dont cp1252) et UTF-8 d’un même texte est assez faible, environ 6% de plus pour le second.
Python2 considérait qu'une chaine est une suite d'octets, alors qu'UTF-8 peut coder des caractères avec 1, 2, 3 ou 4 octets :
Python3 privilégie l’UTF-8 et a modifié manipulation des chaines : pour la chaine ch="ôté", ch[0] vaut le caractère ô. C’est extrêmement utile lors de décomposition de chaines. En python3 :
Note : afin de ne pas multiplier les cas, la suite ne considèrera plus que l’encodage UTF-8. Dans les scripts en python2 uniquement, la première ligne (après l’éventuel #! /usr/bin/python2.7 ) devait être :
Afin de gérer l’Unicode, python2 avait recours aux méthodes encode() et decode(), qui devait préciser le type d’encodage. Dans une console en latin1 :
En UTF-8, le "ê" est représenté par l’octet \xea, qui vaut 234, son rang unicode, mais est sauvegardé avec deux octets \xc3\xaa ; en latin1, ce caractère est lu comme étant deux octets qui forment le caractère.
En python2, La fonction unicode() fait exactement la même chose :
encode() semblait poser un problème en python2 (cela a été discuté sur plusieurs forums) :
En python3, la méthode encode() transforme une chaine en objet 'bytes' selon un type d’encodage :
où l’on voit que le "ê" est codé avec l’octet 0xea (234) en dans l’encodage ISO8859-1 et les deux octets 0xc3 (195) et 0xaa (170) en UTF-8.
Note : encode() étant une méthode pour chaines, "chaine".encode(encodage) et str.encode("chaine", encodage) sont deux expressions équivalentes.
En python3, la méthode byte.decode() transforme un objet "bytes" en chaine selon un type d’encodage :
La tentative de décoder avec ISO8859-1 un objet ’bytes’ issu d’un encodage UTF-8 produit ici deux caractères.
Note : decode() est une méthode pour les objets ’bytes’ :
Python3 dispose de la fonction ascii() qui transforme toute chaine (ou tout objet python comme les dictionnaires, liste, etc.) en une représentation en ASCII :
repr(objet) conditionne un objet pour son affichage complet sous forme de chaine, c’est par exemple intéressant pour sauvegarder les variables dans un fichier.
En python2 / UTF-8 :
Ce codage \#e0 a été retenu pour les octets-caractères non-ASCII du type bytes.
En python3, cela donne :
Python2 disposait d’un objet unicode et d’une fonction unicode(), et même si un caractère spécial était codé en plusieurs octets, sa longueur unicode valait 1 :
Python3 a gardé l’écriture u"", qui est un équivalent à "" et est considéré en python3 comme un objet ’str’ :
La fonction unicode(chaine, encodage) permettait de transformer une chaine codée sur un octet en chaine unicode :
0xa4 correspond au décimal 164 du codage des latin1 et cp1252 et au point de code 164 de l’Unicode, où se situe le caractère ¤ (currency sign)
En python3, unicode() n’existe plus, les chaines étant nativement en utf-8. Il y est très simple d’utiliser ord() capable de situer tous les points «unicode» :
Python2 connaissait une fonction spéciale convertissant un nombre dépassant 255 en son caractère ’Unicode’ :
Python3 a étendu la fonction chr() à tous les points unicode :
ustr.center(n[,car]) retourne une chaine entourée d’espaces dans une chaine de n caractères. car propose un autre caractère de remplissage que l’espace.
ustr.lower() retourne une chaine Unicode en minuscules (même les lettres accentuées
ustr.ljust(n[,"c"]) aligne ustr à gauche dans une chaine de n caractères avec un remplissage d’espaces; "c" peut remplacer l’espace de remplissage éventuel
ustr.count(usub[,start,end]) nombre de fois que la sous-chaine se retrouve dans la chaine ustr, éventuellement limitée à [start,end]. Attention : u"blabla" ne se retrouve qu’une fois dans u"blablabla"
ustr.startswith(sub[,start,end]) True si la chaine commence avec sub (ou si sub est situé à la position start. sub peut être un tuple de chaines à tester
ustr.partition(chaine) renvoie un tuple en trois parties : la partie de chaine Unicode jusqu’au séparateur, le séparateur puis le reste de la chaine Unicode
ustr.translate(table) retourne une chaine où des caractères sont remplacés selon une table (ne semble pas fonctionner comme dans le module string)
En python2, type() appliqué à une valeur renvoyait :
En python3, le retour de la fonction type se libelle différemment :
Dans les deux cas, la valeur retournée par type() est un objet de type type, pas une chaine :
...ce qui signifie que type(9.1) ==<class 'float'> ne peut fonctionner, il faut utiliser
Attention : int n'est pas un mot réservé et peut être également utilisé comme variable.
En python2, type(bytes("é")) retournait <type 'str'>
En python3, type(bytes("é", "latin1")) retourne <class 'bytes'>
S’il est possible en python2 de réaliser une chaine 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 255e caractère Unicode, 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 :
Attention : b"\x217" représente deux bytes : le premier \x21 code la valeur 33 en deux chiffres hexadécimaux (b'!') et le second est le caractère 7, soit l’octet 45.
Mais le plus simple est de constituer une liste pour ensuite la transformer en objet ’bytes’ :
C'est utilisé pour sauvegarder des fichiers binaires avec open("monfichier.bin", "wb")
En python2,les lettres accentuées n’étaient pas considérées comme des caractères alphabétiques : print("é".isalpha()) renvoyait False
En python3 print("é".isalpha()) renvoie True
En python2, type([]) retournait <type 'list'>
type([]) retourne < class 'list'>
Rappelons la façon de s’assurer qu’une variable est une liste (== "<class 'list'>" ne fonctionne pas) :
Attention : beaucoup de fonctions qui retournaient des listes en python renvoient maintenant des objets spécifiques
En python2 range() créait d’abord un objet de type 'list' (ce qui peut prendre un certain temps et encombrer la mémoire) et puis le parcourait.
Pour éviter cela, xrange() générait les nombres un à un :
En python3, range() a repris cette caractéristique et xrange() est supprimé. Ce n’est plus une liste qui est créée mais un itérateur spécial <class 'range'>. Pour obtenir une liste comme en python2, il suffit d’écrire list(range()) en python3 :
En python2, les fonctions filter(), map() et zip() renvoyaient des listes [] ou des chaines "". Par exemple,
Les fonctions intégrées filter(), map() et zip() renvoient en python3 des objets de classes (ou types) 'filter', 'map'et 'zip', objets itérables que l’on peut transformer en chaine ou en liste :
Remarquons que ces filter() et map() peuvent remplacé par une liste définie en compréhension) :
En python2, type({}) retournait <type 'dict'>.
type({}) retourne <class 'dict'>
has_key() était utilisé en python2 pour vérifier qu’une clé existe dans un dictionnaire :
.has_key est maintenant supprimé pour le mot-clé in (existe déjà au moins depuis python2.7) :
En python2, les méthodes pour dictionnaires renvoyaient des listes :
Les méthodes .keys(), .values() et .items() des { dictionnaires } renvoient en python3 maintenant des objets de classes (ou types) dict_keys, dict_values et dict_items, ce qui signifie que le référencement par index xx[n] et des méthodes telles que .pop() ne sont plus applicables en python3 ; il est cependant possible de transformer ces objets en listes :
En python2, il était possible de comparer des dictionnaires :
En Python 3, les dictionnaires ne peuvent plus être comparés avec <, >, <= ou >= car ces comparaisons n'ont pas beaucoup de sens. Seule l'égalité (==, !=) reste définie :
En python2, max() et min() retrouvaient toujours la clé maximale ou minimale d’un dictionnaire, avec la hiérarchie 0 < {} < [] < set() < "" < tuple().
En python3, max() et min() ne fonctionnent que si toutes les clés sont de même classe / type.
Note : Python connait depuis la version 2.7 une nouvelle forme de dictionnaire : OrderedDict, qui conserve la mémoire de l’ordre de ses éléments.
En python2, les ensembles étaient affichés set([1, 2, 3]) par la console :
En python3, les ensembles sont affichés {1, 2, 3} par la console :
Cela ne pose pas trop de problèmes, si on utilise eval() pour relire un fichier contenant l'ancien format contenant set([1, 2, 3]) issu d’une sauvegarde en python2 :
Python2 permettait cette syntaxe :
Python3 exige les parenthèses pour le commentaire :
Les noms des variables et fonctions peuvent en python3 comporter des lettres accentuées, caractères non latins et idéogrammes. À ne pas utiliser dans le cadre d’un développement international.
Comme print n’est plus un mot réservé en python3, il est possible de l’utiliser comme variable, ce qui empêche toutefois l’utilisation de la fonction print().
print() remplace le mot-clé print
Pour plus de détail sur print(), voir cette page
print("Eggs & spam") # remplace print "Eggs & spam" de python2
print("J'ai", 23, "ans", sep=" - ") # remplace l'espace (séparateur par défaut) par une chaine
print("Eggs", end="/") # remplace le saut de ligne par un caractère (ou une chaine).
import time
for i in range(10) :
print("*", end ="", flush =True)
time.sleep(.3)
>>> "{} et {}".format("Romeo", "Juliette")
Romeo et Juliette
>>> f"{12.5:10.2e} en notation 'exponentielle'"
" 1.25e+01 en notation 'exponentielle'"
Fonctions supprimées ou déplacées
from __future__ import
apply() est supprimé
#! /usr/bin/python2.7
def quoi(a, b, x, y):
return a, b, x, y
print apply(quoi, "wz", {"x":27, "y": 19})
('w', 'z', 27, 19)
def quoi(*tup) :
print(tup)
print(type(tup))
quoi(1, 2, 3)
(1, 2, 3)
<class 'tuple'>
def quoi(**dic) :
print(dic)
print(type(dic))
quoi(a=1, b=2, c=3)
Comparaisons
cmp() est supprimé en python3
def cmp(x, y) : return (x > y) - (x < y)
<, <=, > et >=)
Les comparaisons entre types différents ne sont plus permises
0 < {} < [] < set() < "" < tuple()
>>> {1:3, "b":3} < {"d":4, 1:3}
True
>>> {1:3, "b":3, "a":12} < {"d":4, 1:3}
False
>>> {"1":2} < {"3":5}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
>>> ["2", 3] < ["1", 6]
False
>>> [3, "2"] < ["1", 6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'int'
>>> mondic ={"c":5, "a":3, "b":2} ; dict(list(sorted(mondic.items())))
{'a': 3, 'b': 2, 'c': 5}
execfile() est supprimé en python3
exec(open(nomdefichier).read())
with open("essai.py") as df:
exec(df.read())
file() est supprimé en python3
with open("fichier.txt", "w") as descr :
descr.write("montexte")
with open("monfichier.txt", "w") as descr :
descr.write("montexte")
print >> fd, data est remplacé par print(data, file =fd)
fd =open("log.txt","a") # ouverture en ajout d'un fichier
print >> fd, "Salut, tout le monde" # sortie vers log.txt (avec fin de ligne)
descr.close() # inscrit les données et ferme le fichier
with open("mon_fichier.txt", "a") as fd : # également à partir de python2.6
print("Salut, tout le monde", file =fd)
print("Ajout d'une chaine", file =open("monfichier.txt", "a"))
raw_input() est remplacé par input()
>>> raw_input("Saisir un calcul: ")
Saisir un calcul: 3 *5 +2
'3 *5 +2'
>>> input("Saisir un calcul: ")
Saisir un calcul: 3 *5 +2
17
>>> input("Saisir un calcul: ")
"Saisir un calcul: 3 *5 +2
'3 *5 +2'
>>> eval(input("Saisir un calcul: "))
"Saisir un calcul: 3 *5 +2
17
intern("") est déplacé dans le module sys
import sys
a =sys.intern("Une chaine")
reduce() est déplacé dans le module functools
>>> import functools
>>> functools.reduce(lambda x, y : x *y, range(1, 7))
720
Nombres
long() et le suffixe L sont supprimés
coerce() est supprimé
>>> print coerce(5, 2e3), coerce(0, 2 +1j)
(5.0, 2000.0) (0j, (2+1j))
<> est supprimé
0o devient le préfixe octal en python3
Divisions
>>> 7. /4
1.75
>>> from __future__ import division
>>> 7 /4
1.75
#! /usr/bin/python -Qnew
>>> 8 /2 ; type(8 /2)
4.0
<class 'float'>
>>> 7 //4 ; -7 //4
1
-2
round() est plus précis
>>> round(3.14159, 2) ; round(2143, -2) ; type(round(3.14))
3.1400000000000001
2100.0
<type 'float'>
>>> round(3.14159, 2) ; round(2143, -2) ; type(round(3.14))
3.14
2100
<type 'int'>
>>> round(2.5) ; round(3.5)
3
4
>>> round(2.5) ; round(3.5)
2
4
Chaines
UTF-8 est la norme en python3
_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _A _B _C _D _E _F
\x0_
7\a8\b9\t10\n11\v12\f13\r
\x1_
\x2_
32 33!34#35"36$37%38&39’40(41)42*43+44,45-46.47/ \x3_
48049150251352453554655756857958:59;60<61=62>63? \x4_
64@65A66B67C68D69E70F71G72H73I74J75K76L77M78N79O \x5_
80P81Q82R83S84T85U86V87W88X89Y90Z91[92\93]94^95_ \x6_
96`97a98b99c100d101e102f103g104h105i106j107k108l109m110n111o \x7_
112p113q114r115s116t117u118v119w120x121y122z123{124|125}126~127
#! /usr/bin/python2.7
# pas de lettre accentuée, même dans un commentaire !
print("Salut, tout l'monde")
File "./essai.py", line 2
SyntaxError: Non-ASCII character '\xea' in file ./0.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
#! /usr/bin/python2.7
# -*- coding: latin1 -*-
print("Ça va plutôt bien")
Ça va plutôt bien
L’encodage UTF-8
>>> print("\xe9")
�
é
#! /usr/bin/python2.7
# -*- coding: utf-8 -*-
print("Ça va plutôt bien")
Codage des caractères en UTF pour python 2 et 3
#! /usr/bin/python2.7
# -*- coding: utf-8 -*-
chaine ="ôté"
print(len(chaine)) # la réponse est 5, 'ô' et 'é' valant chacun deux octets
print(chaine[0]) # la réponse est '�', premier octet du doublet représentant 'ô', qui n’a pas de sens en UTF-8 s'il est isolé
#! /usr/bin/python3
chaine ="ôté"
print(len(chaine)) # la réponse est 3, chaque caractère valant un
print(chaine[0]) # la réponse est 'ô'
# -*- coding: utf-8 -*-
>>> # -*- coding: utf-8 -*-
>>> ch="être"
>>> uch =ch.decode("utf8") ; uch
u'\xeatre'
>>> lch =ch.decode("latin1") ; lch
u'\xc3\xaatre'
>>> unicode("être", "latin1")
u'\xc3\xaatre'
>>> "ê".decode("utf8")
u'\xea'
>>> "ê".decode("utf8").encode("utf8")
'\xc3\xaa'
>>> ch ="être"
>>> ch.encode("latin1")
b'\xeatre'
>>> ch.encode("utf8")
b'\xc3\xaatre'
>>> str.encode(ch, "utf8")
b'\xc3\xaatre'
>>> b"\xc3\xaatre".decode("utf-8")
'être'
>>> b"\xc3\xaatre".decode("latin1")
'être'
>>> bytes.decode(b"\xe9", "latin")
'é'
>>> print(ascii("pµə"))
"'p\xb5\u0259'"
>>> a ="C'est déjà ça"
>>> a; print(a); print(repr(a))
"C'est d\xe9j\xe0 \xe7a"
C'est déjà ça
"C'est d\xe9j\xe0 \xe7a"
>>> a ="C'est déjà ça"
>>> a ; print(a); print(repr(a))
"C'est déjà ça"
C'est déjà ça
"C'est déjà ça"
Unicode
>>> u"œ"; type(u"œuf"); len(u"œuf")
u'\u0153uf'
<type 'unicode'>
3
>>> u"œ"; type(u"œuf"); len(u"œuf")
'œ'
<class 'str'>
3
>>> unicode(chr(164), "latin1")
u'\xa4'
>>> unicode(chr(164), "latin9")
u'\u20ac'
0x20ac correspond au décimal 164 du codage latin9 (ou iso8819-15), mais au point de code 8364 de l’Unicode (0x20ac en hewadécimal)), où se situe le caractère € (euro sign)
>>> ord("€")
8364
>>> unichr(0x20ac)
€
>>> chr(0x20ac)
€
Formatage
ustr.zfill(n) remplit la gauche d’un nombre avec autant de zéros qu’il faut pour arriver à n caractères (ne limite pas la longueur de la chaine à n caractères)
ustr.expandtabs(n) retourne une chaine où des espaces remplacent les tabulations pour un alignement sur les colones octuples si n n’est pas précisé
ustr.upper() retourne une chaine Unicode en majuscules (même les lettres accentuées
ustr.swapcase() retourne une chaine avec changement de casse
ustr.capitalize() retourne une chaine avec la première lettre en capitale
ustr.title() retourne une chaine avec la première lettre de chaque mot en capitale
rjust(n[,c]) aligne à droite dans une chaine de n caractères; c peut remplacer l’espace de remplissage éventuel
ustr.strip([c]) retourne une chaine débarrassée des espaces (au sens large) l’entourant. c pour "éplucher" d’autres caractères
ustr.lstrip([c]) seulement à gauche
ustr.rstrip([c]) seulement à droite
Compter, chercher, remplacer
ustr.find(str[,start,end]) renvoie la première occurrence de str dans ustr, éventuellement limité dans la portion [start:end] de la chaine (-1 si inexistante)
ustr.rfind() renvoie la dernière occurrence de str dans ustr, éventuellement limité dans la portion [start:end] de la chaine (-1 si inexistante)
ustr.index() et rindex() comme find() mais ValueError au lieu de -1
ustr.replace(old,new[,nb]) remplace les [n premières] occurrences old par new
ustr.endswith(…)
Éclatements et liaisons
ustr.rpartition(chaine) La première partie de la chaine Unicode court jusqu’au dernier séparateur, le séparateur et puis le reste.
ustr.split([sep,max]) renvoie une liste de chaines découpées par un séparateur, avec un éventuel nombre maximal de coupures. split([None,max]) pour un nombre limité de coupures avec l’espace comme séparateur
ustr.rsplit([sep,max])
ustr.splitlines()
u"sep".join(liste) retourne une chaine résultat de la concaténation des chaines d’une liste de chaines (avec un éventuel séparateur)
type() ne retourne plus le même «type»
>>> type(.977)
<type 'float'>
>>> type(.977)
<class 'float'>
>>> type(type(.977))
<class 'type'>
>>> a="123" ; type(a) ==type(0.0)
True
>>> a=123 ; type(a) ==int
True
Le type 'bytes' (octet)
>>> ba =b""; ba +=b"A"; ba +=b"\x217"; ba
b'A!7'
>>> bytes([0, 255, 45, 95, 250])
.isalpha()
Listes
var =[0, 1, 2, 3] ; print(type(var) ==type([]))
xrange() est supprimé
for i in range(10**8) :
print i
for i in xrange(10 **8) :
print i
>>> list(range(3, 10, 2))
[3, 5, 7, 9]
Certaines fonctions ne renvoient plus de liste
>>> filter(lambda x: 115 < ord(x) < 125, "python")
'yt'
>>> map(ord, "python")
[112, 121, 116, 104, 111, 110]
>>> zip([1, 2, 3], ("a", "b", "c"))
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> "".join(filter(lambda x: 115 < ord(x) < 123, "python"))
'yt'
>>> list(map(ord, "python"))
[112, 121, 116, 104, 111, 110]
>>> list(zip([1, 2, 3], ("a", "b", "c")))
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> "".join([x for x in "python" if 115 < ord(x) < 123])
'yt'
>>> [ord(x) for x in "python"]
[112, 121, 116, 104, 111, 110]
Dictionnaires
>>> dico ={"a":12, "b":34} ; dico.has_key("a")
True
>>> dico ={"a":12 , "b":34} ; "a" in dico
True
>>> dic ={1:3, 2:4} ; dic.keys() ; dic.values() ; dic.items()
[1, 2]
[3, 4]
[(1, 3), (2, 4)]
dic ={1:3, 2:4} ; list(dic.keys()) ; type(dic.values()) ; dic.items()
[1, 2]
<class 'dict_values'>
dict_items([(1, 3), (2, 4)])
>>> a={5:7} ; b={8:9}
>>> a > b ; a < b
False
True
>>> a ={2:8} ; b={6:7}
>>> a < b
Traceback (most recent call last):
File '<stdin>', line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
>>> max({1:2, "j":4})
Traceback (most recent call last):
File '<stdin>', line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'int'
Ensembles
>>> a ={1, 2, 3} ; a
set([1, 2, 3])
>>> a ={1, 2, 3} ; a
{1, 2, 3}
with open("svg.txt", "w") as fd :
print >> fd, set([1,2,3])
with open("svg.txt") as fd :
print(eval(fd.read()))
raise
>>> raise KeyboardInterrupt, "Commmentaire facultatif"
>>> raise KeyboardInterrupt("§ Mon commentaire §")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyboardInterrupt: § Mon commentaire §
Variables
>>> print = 43
>>> print("Salut, Monde")
Traceback (most recent call last):
File "