Aller au contenu

Encodage

Unicode

Dans un texte, les mots et les phrases sont créés à partir de caractères. La lettre latine « á », l’idéogramme chinois « 請 » ou le caractère Devanagari « ह » sont des exemples de caractères.

Les caractères sont regroupés dans un registre de caractères (également appelé répertoire), appelé ensuite registre de caractères codés lorsqu'un chiffre précis est attribué à chaque caractère, nommé point de code. Ces points de code sont représentés dans l’ordinateur par un octet ou plus.

L’encodage de caractères (ou encoding) est la clé qui structure les points de code en octets dans la mémoire de l’ordinateur, puis lit les octets à nouveau en points de code.

Par exemple, le caractère « É » a pour point de code U+00C9 dans la norme Unicode. Il est encodé selon le jeu de caractères UTF-8 sur deux octets : C389.

UTF-8 est compatible avec le jeu de caractère ASCII. Par exemple, le caractère « j » a pour point de code U+006A dans la norme Unicode. Il est encodé selon le jeu de caractères ASCII sur un octet : 6A. Selon le jeu de caractères UTF-8, il est également encodé sur un octet : 6A.

Pour convertir un point de code Unicode (UCS code number) en sa représentation selon le jeu de caractère UTF-8, voir la très bonne explication du manuel Linux : utf8(7) - Linux man page.

Important

Utiliser UTF-8. Partout. Tout le temps.
Décoder systématiquement toutes les entrées du programme.
Encoder systématiquement toutes les sorties du programme.

Code source

L'encodage par défaut pour le code source Python 2 est ASCII.

En revanche, l'encodage par défaut pour le code source Python 3 est UTF-8, l'implémentation la plus célèbre d'Unicode.

Pour éviter les erreurs (particulièrement en Python 2), il est nécessaire de déclarer l'encodage utilisé dans le fichier source, en début de programme :

# -*- coding: utf_8 -*-

Le type String

En Python 2.7, les chaînes de caractères (<type 'str'>) sont des séquences d'octets. Il faut préfixer une chaîne de caractères par un u pour obtenir une chaîne Unicode (<type 'unicode'>).

Depuis Python 3, les chaînes de caractères (<class 'str'>) sont des chaînes Unicode. Il faut préfixer une chaîne de caractères par un b pour obtenir une séquences d'octets (<class 'bytes'>).

Le type String en Python 3

>>> chaîne_unicode = "éléphant" # encodage UTF-8 par défaut
>>> chaîne_unicode
'éléphant'                      # chaîne de caractères Unicode
>>> type(chaîne_unicode)
<class 'str'>
>>> print(chaîne_unicode)
éléphant                        # chaîne de caractères Unicode

>>> chaîne_octets = chaîne_unicode.encode("utf_8")
>>> chaîne_octets
b'\xc3\xa9l\xc3\xa9phant'       # séquences d'octets
>>> type(chaîne_octets)
<class 'bytes'>
>>> print(chaîne_octets)
b'\xc3\xa9l\xc3\xa9phant'       # séquences d'octets

>>> print(chaîne_octets.decode("utf_8"))
éléphant                        # chaîne de caractères Unicode bien décodée
>>> print(chaîne_octets.decode("ascii", "replace"))
��l��phant                      # chaîne de caractères Unicode mal décodée

Le type String en Python 2.7

>>> chaine_unicode = u"éléphant"
>>> chaine_unicode
u'\xe9l\xe9phant'               # chaîne de caractères Unicode
>>> type(chaine_unicode)
<type 'unicode'>
>>> print(chaine_unicode)
éléphant                        # chaîne de caractères Unicode

>>> chaine_octets = chaine_unicode.encode("utf_8")
>>> chaine_octets
'\xc3\xa9l\xc3\xa9phant'        # séquences d'octets
>>> type(chaine_octets)
<type 'str'>
>>> print(chaine_octets)
éléphant                        # attention, séquences d'octets !

>>> print(chaine_octets.decode("utf_8"))
éléphant                        # chaîne de caractères Unicode bien décodée
>>> print(chaine_octets.decode("ascii", "replace"))
��l��phant                      # chaîne de caractères Unicode mal décodée

En Python 2.7, il est possible de s'affranchir du prefixe u pour déclarer une chaîne Unicode. Attention, le principe d'encodage / décodage reste inchangé :

$ python2.7
>>> from __future__ import unicode_literals
>>> chaine_unicode = "éléphant"
>>> chaine_unicode
u'\xe9l\xe9phant'               # chaîne de caractères Unicode

Résumé du type String

Python 3 Python 2.7 Python 2.7
>>> from __future__ import unicode_literals
>>> type("chaine") <class 'str'>
chaîne Unicode
<type 'str'>
séquence d'octets
<type 'unicode'>
chaîne Unicode
>>> type(u"chaine") <class 'str'>
chaîne Unicode
<type 'unicode'>
chaîne Unicode
<type 'unicode'>
chaîne Unicode
>>> type(b"chaine") <class 'bytes'>
séquence d'octets
<type 'str'>
séquence d'octets
<type 'str'>
séquence d'octets

Ressources