Comment contourner lerreur Python ' UnicodeEncodeError: ' ascii ' le codec ne peut ' encoder le caractère … ' lors de lutilisation dun script Python sur la ligne de commande

Meilleure réponse

Désolé, il ny a pas de réponse simple en une ligne à ce problème.

Imaginez quune chaîne entre dans un programme python via une opération dE / S (lecture depuis un terminal, ou depuis un fichier, ou depuis le réseau), elle se fraye un chemin dans le programme en étant copiée dun endroit à lautre et enfin, il obtient une sortie via une opération dE / S. À n’importe quelle étape du processus, si vous attribuez un code Unicode à une chaîne, vous verrez l’erreur redoutée ascii codec can"t encode.... Malheureusement, il n’existe pas de moyen simple de la corriger autrement que d’y aller grâce à votre code corrigeant tous les points.

Par exemple, considérez:

f\_in = open("filein.txt")

line = f\_in.read()

out\_msg = "The input line was: {line}".format(line=line)

f\_out = open("fileout.txt")

À moins que vous ne sachiez quel encodage a été utilisé lors du stockage de filein.txt, vous allez avoir un comportement bizarre et certains caractères de votre line ressembleront à des ordures. (Remarque: vous avez gagné  » t obtenir lerreur ascii codec can"t encode..., mais les résultats seront néanmoins mauvais.) Vous devez donc utiliser quelque chose comme: f\_in = codecs.open("filein.txt", "rb", "utf-8") et espérer désespérément que celui qui a stocké filein.txt lavait stocké dans utf-8 et non dans lun des autres encodages UTF. (Remarque: utf-8 est compatible avec ascii, donc un fichier qui a été stocké en utilisant lascii normal souvrira correctement en utilisant lencodage utf-8).

À présent, vous aurez évidemment réalisé quà moins que vous ouvrez fileout.txt en utilisant un encodage Unicode approprié, vous allez à nouveau avoir des problèmes et obtenir lerreur ascii codec can"t encode... (si votre out\_msg contient un caractère Unicode). Vous devez donc faire codecs.open("fileout.txt", "wb", "utf-8"). (Remarquez encore: utiliser un encodage utf-8 pour stocker des ascii normaux nest pas un problème, car il est compatible vers le haut, donc si votre texte ne contient pas de caractères unicode non-ascii , le fichier encodé en utf-8 est identique à un fichier ascii normal.)

Ce qui ma fait trébucher, cest que faire ces deux choses nest pas assez bon. Considérez ce code mis à jour:

f\_in = codecs.open("filein.txt", "rb", "utf-8")

line = f\_in.read()

out\_msg = "The input line was: {line}".format(line=line)

f\_out = codecs.open("fileout.txt", "wb", "utf-8")

Cela pourrait toujours vous donner la même erreur redoutée sur le troisième ligne. Cest vrai, le problème est que "The input line was: {line}".format(xxx)" est un str et si line contient tous les caractères Unicode (je veux dire les caractères qui ne peuvent pas être encodés en ascii) vous rencontrez des problèmes.

Le correctif pour cela est:

out\_msg = u"The input line was: {line}".format(line=line)

(Oui, cette ligne est différente de la ligne 3 dans lexemple de code. Il suffit de regarder attentivement.)

Alors voilà. Il faut passer par chaque ligne de votre code et trouvez les endroits où unicode est assigné à str (ou est envoyé à une méthode qui attend un str) et corrigez la destination pour quelle soit unicode au lieu de str.

Pour comprendre unicode en python mieux, jetez un œil à: http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/

Pour comprendre lunicode en général (et je hautement vous recommande de le faire) lisez le minimum absolu de Joel Spolsky « s » que tout développeur de logiciel doit absolument et positivement savoir sur Unicode et les jeux de caractères (Non Excuses!) « : http://www.joelonsoftware.com/articles/Unicode.html

Et pendant que vous en êtes à ce sujet, vous pourriez aussi bien lire: Quelle est la meilleure source pour en savoir plus sur les meilleures pratiques Unicode en python?

Quick « n Dirty Hack: Si vous voulez juste obtenir une sortie imprimée en ascii approximatif, vous pouvez faire:

import unicodedata

line = unicodedata.normalize("NFKD", line).encode("ascii","ignore")

Ceci remplacera tous les caractères non-ascii par léquivalent ascii le plus proche, ou ignorera simplement le caractère si rien nest approprié . Est assez bon pour de nombreuses raisons …

Réponse

Vous devriez convertir vos chaînes Unicode (qui sont faites de caractères, une unité découplée de la taille de la mémoire) en octets en utilisant le bon encodage avant deffectuer des E / S avec.

Par défaut, Python essaie dencoder votre chaîne Unicode en utilisant lencodage ASCII lors de lécriture sur stdout (cest-à-dire en utilisant print ), mais cet encodage ne peut « t représenter chaque caractère Unicode, cest pourquoi vous obtenez cette erreur: » Le codec « ascii » ne peut « t encoder le caractère ». Assez explicite.

Vous devriez choisir un encodage approprié, et encoder votre chaîne Unicode en lutilisant. Par exemple, UTF-8 est un encodage efficace qui peut gérer tous les caractères Unicode. En supposant que foo est une chaîne Unicode, vous pouvez (et devriez) faire: print foo.encode (« utf -8 « ) au lieu de simplement print foo . Assurez-vous simplement que votre terminal ou tout autre appareil comprend lencodage que vous choisissez.Encore une fois: UTF-8 est lencodage le plus populaire pour des scénarios comme celui-ci, vous voudrez probablement lutiliser à moins que vous nayez des besoins très spécifiques.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *