Encoding et jeux de caractères

Jeux de caractères

La langue anglaise est la langue dominante en ce qui concerne l’informatique mais cela n’empêche pas que des programmes anglais manipulent du japonais même si le nombre de caractères est beaucoup plus grand. Les caractères les plus fréquent peuvent être représentés par un octet, soit au plus 256 caractères. Lorsque la langue en contient plus, il faut utiliser plusieurs octets pour un caractères. C’est à ça ce que servent les jeux de caractères : ils définissent la façon de passer d’une suite d’octets à une séquence de caractères et réciproquement. Pour être plus précis, le jeu de caractère désigne l’ensemble de caractères dont le programme a besoin, l’encodage décrit la manière dont on passe d’une séquence de caractères français, japonais, anglais à une séquence d’octets qui est la seule information manipulée par un ordinateur. Le décodage définit le passage inverse. Les langues latines n’ont besoin que d’un octet pour coder un caractère, les langues asiatiques en ont besoin de plusieurs. Il n’existe pas qu’un seul jeu de caractères lorsqu’on programme. Ils interviennent à plusieurs endroits différents :

  • Le jeu de caractères utilisé par l’éditeur de texte pour afficher le programme.

  • Le jeu de caractères du programme, par défaut ascii mais il peut être changé en insérant une première ligne de commentaire (exemple : # -*- coding: utf-8 -*-). Les chaînes de caractères du programme sont codées avec ce jeu de caractères. Ce jeu devrait être identique à celui utilisé par l’éditeur de texte afin d’éviter les erreurs.

  • Le jeu de caractères de la sortie, utilisé pour chaque instruction print, il est désigné par le code cp1252 sur un système Windows.

  • Le jeu de caractères dans lequel les chaînes de caractères sont manipulées. Un jeu standard qui permet de représenter toutes les langues est le jeu de caractères utf-8. Il peut être différent pour chaque variable.

  • Le jeu de caractères d’un fichier texte. Il peut être différent pour chaque fichier.

Depuis la version 3 de Python, toutes les chaînes de caractères sont au format unicode. C’est à dire que le jeu de caractères est le même pour toutes les chaînes de caractères. Pour en changer, il faut encoder le texte avec un jeu spécifique et la fonction encode. Il deviendra une chaîne d’octets ou bytes. La transformation inverse s’effectue avec la méthode decode.

<<<

st = "eé"
print(type(st))
print(len(st))

sb = st.encode("latin-1")
print(type(sb))
print(len(sb))

>>>

    <class 'str'>
    2
    <class 'bytes'>
    2

L’exemple précédent montre que la fonction len retourne le nombre de caractères mais cela ne correspond pas au nombre d’octets que cette chaîne occupe en mémoire.

<<<

st = "eé"
print(type(st))
print(len(st))

sb = st.encode("utf-16")
print(type(sb))
print(len(sb))

>>>

    <class 'str'>
    2
    <class 'bytes'>
    6

Un autre jeu, une autre longueur.

Fichiers

Comme Python utilise un jeu unique, il suffit de faire attention où on récupère les chaînes de caractères et au moment où on les transfère. C’est ce qu’on appelle les entrées sorties comme lire ou écrire un fichier. Par défaut un fichier est écrit avec le jeu de caractères du système d’exploitation. Pour un préciser un autre, il faut spécifier le paramètre encoding. Toutes les chaînes de caractères seront lues et converties au format unicode depuis ou vers l’encoding spécifié.

with open("essai.txt", "r", "utf-8") as f:
    text = f.read()

Méthodes

encode( [enc[,err]])

Cette fonction permet de passer d’un jeu de caractères, celui de la variable, au jeu de caractères précisé par enc à moins que ce ne soit le jeu de caractères par défaut. Le paramètre err permet de préciser comment gérer les erreurs, doit-on interrompre le programme (valeur 'strict' ou les ignorer (valeur 'ignore'). La documentation Python recense toutes les valeurs possibles pour ces deux paramètres aux adresses

decode([enc[, err]]

Cette fonction est la fonction inverse de la fonction encode. Avec les mêmes paramètres, elle effectue la transformation inverse.

Encodings par défaut

Le programme suivant permet d’obtenir le jeu de caractères par défaut et celui du système d’exploitation.

<<<

import sys
import locale
import platform
print(sys.platform)
print(platform.architecture)
print(sys.getdefaultencoding())
print(locale.getdefaultlocale())

>>>

    linux
    <function architecture at 0x7fee134e4700>
    utf-8
    ('en_US', 'UTF-8')

Les problèmes d’encoding surviennent parfois car on précise rarement l’encoding du programme Python ni le programmeur ne contrôle pas facilement celui de la sortie (print). Ces deux paramètres changent selon les éditeurs ou les systèmes d’exploitations.