• Aucun résultat trouvé

Conversion (encodage/décodage) des chaînes

Nous entrons à présent dans le vif du sujet. Pour leur traitement à l'intérieur d'un script Python, il faudra fréquemment convertir les chaînes de caractères, du type string au type unicode, ou vice-versa. Vous devez donc savoir comment effectuer ces conversions. Python vous fournit fort heu-reusement les outils nécessaires, sous la forme de méthodes des objets concernés.

Conversion d'une chaîne string en chaîne unicode

Considérons un script dans lequel on utilise la fonction interne raw_input() pour accepter les en-trées d'un utilisateur. Cette fonction renvoie toujours une valeur de type string, laquelle est enco-dée en Latin-1, en Utf-8, ou encore une autre norme, suivant l'encodage utilisé par défaut sur le poste de travail de cet utilisateur. Supposons par exemple qu'il s'agisse d'Utf-8. Pour convertir cette chaîne Utf-8 en chaîne unicode, vous appliquerez à cet objet string la méthode decode(), avec l'argument "Utf-8" (Vous pouvez aussi utiliser "utf-8", "Utf8" ou "utf8"). Exemple :

print "Veuillez entrer une chaîne avec des caractères accentués, svp :"

chs = raw_input() # la chaîne est entrée est un objet de type string chu = chs.decode("utf-8") # conversion en chaîne unicode (décodage)

À la troisième ligne de cet exemple, la variable chu se voit affecter une chaîne de type unicode.

Vous pouvez vous en assurer, par exemple en extrayant de cette chaîne l'un ou l'autre caractère accentué, ou en testant sa longueur comme nous l'avons fait dans les exemples précédents. Vous pouvez aussi plus simplement faire appel à la fonction interne type(). Ainsi par exemple, l'ins-truction :

print type(chs), type(chu)

ajoutée à la fin du petit script script ci-dessus, provoquerait l'affichage :

<type 'str'> <type 'unicode'>

Si le poste de travail de l'utilisateur utilise l'encodage Latin-1 (Cas de nombreux postes Windows), vous pouvez également décoder la chaîne entrée. Il vous suffit de remplacer l'argument "Utf-8"

par "Latin-1" (ou encore "Latin1", "latin-1", "latin1").

Conversion d'une chaîne unicode en chaîne string

Considérons à présent que vous souhaitiez mémoriser une chaîne de caractères dans un fichier texte. Si la chaîne à mémoriser est du type unicode dans votre script, vous devez d'abord choisir un encodage, et la convertir en string avant de pouvoir l'enregistrer. Pour ce faire, vous applique-rez à cet objet unicode sa méthode encode(), avec l'argument correspondant à l'encodage souhai-té. Par exemple, pour enregistrer des chaînes avec l'encodage Utf-8, vous ferez :

chu = u"Chaîne avec accents : déjà Noël !" # chaîne unicode

chs = chu.encode("utf8") # conversion unicode -> string of = open("MonFichier", "w")

of.write(chs) of.close()

Attention : Vous ne pouvez pas enregistrer une chaîne unicode telle quelle dans un fichier texte, car le choix d'un encodage est indispensable. Si vous essayez par exemple :

chu = u"Chaîne avec accents : déjà Noël !" # chaîne unicode of = open("MonFichier", "w")

of.write(chu) of.close()

vous allez obtenir un message d'erreur similaire au suivant :

Traceback (most recent call last):

File "test.py", line 5, in <module>

of.write(chu)

UnicodeEncodeError: 'ascii' codec can't encode character u'\xee' in position 3:

ordinal not in range(128)

Explication : Du fait que vous ne précisez aucun encodage, Python essaie d'encoder la chaîne uni-code chu avec l'encodage par défaut, à savoir presque toujours ASCII46. Cela ne marche évidem-ment pas avec les caractères accentués, ce qu'indique assez claireévidem-ment le message d'erreur47.

46Attention : cet encodage par défaut de Python reste toujours ASCII, même si vous avez pris la peine d'indiquer votre encodage par défaut en début de script, à l'aide d'une ligne telle que : # coding:Utf-8

-*-Une ligne de ce genre indique en effet à Python l'encodage que vous utilisez pour toutes les chaînes de texte littérale, les commentaires, etc. que vous insérez vous-même dans votre script. Elle ne force pas l'encodage des entrées/sorties. Il est possible de modifier ce comportement par défaut de Python, mais cela sort du cadre de ce manuel.

47En informatique, on appelle codec (codeur/décodeur) tout dispositif de conversion de format. Vous rencontrerez par exemple de nombreux codecs dans le monde du multimedia (codecs audio, vidéo, ...). Python dispose de nombreux codecs pour convertir les chaînes de caractères suivant les différentes normes en vigueur.

Conversion d'une chaîne Utf-8 en Latin-1, ou vice-versa

Si vous avez compris le fonctionnement des méthodes decode() et encode() décrites dans les ru-briques précédentes, vous pouvez bien évidemment les appliquer à la conversion d'une chaîne de type string, d'un format d'encodage à un autre :

# Conversion Utf-8 -> Latin-1 :

chLat = chUtf.decode('Utf8').encode('Latin1')

Vous remarquerez encore une fois que la composition d'instructions permet d'éviter le passage par une variable intermédiaire. La chaîne d'origine chUtf est convertie en unicode, puis re-convertie en string, en une seule opération.

# Conversion Latin-1 -> Utf-8 :

chUtf = chLat.decode('Latin1').encode('Utf8')

Quand faut-il convertir ?

Si vous travaillez dans un environnement « ancien » utilisant toujours l'encodage ISO-8859-1 par défaut (ce qui est encore le cas de nombreux postes de travail fonctionnant sous Windows), vous pouvez peut-être provisoirement ignorer la question, et vous contenter de traiter toutes vos chaînes de caractères en objets de type string.

Ce n'est cependant pas une bonne idée si vous avez l'ambition de vous tenir au courant de l'évolu-tion des techniques informatiques. Vous devrez tôt ou tard vous préoccuper de rendre vos pro-grammes compatibles avec les exigences de l'internationalisation. Et le plus tôt sera le mieux.

Et si votre poste de travail fonctionne avec un système d'exploitation aux normes modernes, tel Ubuntu Linux, par exemple, vous n'avez déjà plus le choix : vous devez comprendre ce que sont les types string et unicode de Python, et vous devez maîtriser leurs conversions réciproques.

Ce n'est finalement pas très compliqué : en résumé, il faut retenir que :

• Toutes les entrées/sorties de chaînes de caractères doivent être du type string.

• Avant d'effectuer sur une chaîne toute opération nécessitant un accès à ses caractères indivi-duels, il faut impérativement la convertir au préalable en objet unicode.

• Les opérations qui ne nécessitent pas un accès aux caractères individuels peuvent souvent en-core être effectuées directement sur les chaînes de type string, sans conversion préalable en unicode.

• Convertir une chaîne unicode en string constitue un encodage. On l'effectue à l'aide de la mé-thode encode() appliquée à cet objet. Exemple : chs = chu.encode('Latin-1').

• Convertir une chaîne de type string en unicode constitue un décodage. On l'effectue en appli-quant la méthode decode() à cet objet. Exemple : chu = chs.decode('Utf-8').

Dans la suite de ce chapitre, nous rencontrerons divers exemples d'application de ces règles. Vous vous familiariserez vite avec elles.

À l'avenir, il sera certainement plus rationnel d'effectuer toutes les manipulations de chaînes à l'intérieur de vos programmes à l'aide du seul type unicode, et de réserver le type string aux entrées/sorties. Dans la suite de ce livre, cependant, nous utiliserons encore beaucoup le type string, essentiellement pour des raisons « historiques » : la plus grande grande partie des scripts que nous vous y présentons comme exemples ont en effet été développés sur des machines utilisant toujours la norme ancienne Latin-1.

Nous n'y avons ajouté des conversions qu'aux seuls endroits où cela s'avérait indispensable pour que ces scripts s'exécutent correctement sur des machines récentes. Dans vos propres scripts, prenez l'habitude d'utiliser

préférentiellement le type unicode pour traiter toutes vos chaînes de caractères.