Essais réalisés avec Python 2.6
Depuis le temps que je me cogne (comme tant d'autres) contre les subtilités de l'encodage des chaines de caractères, j'ai investi un peu de temps pour y voir plus clair.
L'objectif de cette page est d'identifier les principes de traitement à utiliser pour intégrer, manipuler, afficher et enregistrer des chaines de caractères comportant, par exemple, des caractères accentués.
A noter que des erreurs de traitement sur ce sujet peuvent aller jusqu'à planter un programme!
L'ordinateur, qui est très bête, ne sait pas ce qu'est un caractère comme “A”. Il ne sait que contenir des codes numériques comme 65 (ou 0x41 en hexa). Le fait de rattacher le nombre 65 à la lettre “A” n'est qu'une convention.
Ainsi, au départ de l'informatique, il a été établi une liste de correspondance très simple, qui ne comportait que:
Cette liste de correspondance, associant un nombre au dessin d'un caractère, ne nécessitait seulement que des nombres de 0 à 127, soit des octets (8 bits) sans le dernier bit de gauche. On parle de codage “ASCII” (http://fr.wikipedia.org/wiki/ASCII).
Elle a été complétée plus tard pour contenir des caractères supplémentaires comme les caractères accentués “é”, “è”, “ô”, …, ainsi que d'autres caractères de contrôle… Mais là, il a fallu étendre les nombres pour utiliser la partie 128 à 255 des octets.
En fait, il y a actuellement de nombreuses normes pour représenter les caractères particuliers des pays, tout en restant à l'intérieur des octets (0 à 255). Les principaux pour nous pays de langue française sont:
L'avantage est que les premiers caractères de 0 à 127 sont sensiblement les mêmes que dans le codage ASCII. Pour les caractères supplémentaires, il y a cependant quelques différences dont il faut se méfier. Par exemple entre cp1252/ANSI et iso-8859-1 :http://www.alanwood.net/demos/charsetdiffs.html.
Pour les autres pays ayant des caractères non latins, il existe d'autres codages de caractères comme l'iso-8859-5 pour l'alphabet cyrillique, l'iso-8859-7 pour l'alphabet grec moderne, etc…
Mais maintenant, comment faire pour que les mêmes programmes puissent, sans changer d'encodage de caractères, être utilisés en Grèce, en Inde, en Russie, en Chine, etc… Ceci d'autant plus qu'avec Internet, les échanges sont devenus quotidiens, et rien ne doit vous empêcher de converser par mail avec des chinois ou des russes. La multiplicité des caractères exclut qu'on reste à l'intérieur des octets (0 à 255): alors, comment on fait? On invente l'UNICODE! Voir http://fr.wikipedia.org/wiki/Unicode.
Il y a en fait plusieurs types d'unicode: UCS-2, UTF-8, UTF-16, UTF-32, …
En simplifiant, pour nous, français utilisant Python:
Avec Python 2.6, on peut toujours travailler avec des codages sur un octets, par exemple avec l'iso-8859-1/latin-1 (ou cp1252 sous Windows), mais on va de plus en plus travailler en Unicode. Et ceci, surtout si on travaille en multiplateforme et en multilingue. En ce qui me concerne, comme je fais le plus souvent du développement windows-linux, je suis obligé de travailler le plus souvent en utf-8, y compris pour les codes sources, qui est l'encodage par défaut des Linux modernes.
Les codages utilisables par Python sont ici: http://docs.python.org/library/codecs.html#standard-encodings
Si on veut travailler en Unicode avec Python, voici quelques principes simples à respecter:
Remarques:
Pour reproduire les tests ci-dessous, je vous suggère de vous munir de 3 outils supplémentaires:
En ce qui concerne le développement multiplateforme sous Windows, la 1ère difficulté est de trouver un outil de développement qui permette l'édition du code source en UTF-8, ainsi que les fins de ligne UNIX. En ce qui me concerne, j'utilise “Easy Eclipse pour Python”. L'éditeur Scite marche aussi. Mais, par exemple, l'éditeur de texte Context, que j'utilisais beaucoup, ne le permet pas.
Quand vous écrivez le code d'un programme, vous utilisez un éditeur de texte qui utilise un encodage vous permettant, par exemple, d'insérer une chaine de caractère comportant des caractères accentués. Quand vous enregistrez le code sur disque, vous devez pouvoir choisir l'encodage utilisé dans l'enregistrement (ou, au moins, le connaitre). Et, pour renseigner python lors de l'exécution, vous devez l'informer de l'encodage du fichier en écrivant la ligne suivante tout au début du code juste après le shebang. Par exemple avec l'encodage “utf-8”:
# -*- coding: utf-8 -*-
Pour comprendre la liaison entre ces éléments, vous pouvez faire les manips suivantes: