web-dev-qa-db-fra.com

Python UnicodeDecodeError - Suis-je en train de mal comprendre le codage?

Vous pensez pourquoi cela ne fonctionne pas? Je pensais vraiment que "ignorer" ferait la bonne chose.

>>> 'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 4: ordinal not in range(128)
54
Greg

… Il y a une raison pour laquelle on les appelle des "encodages"…

Un petit préambule: pensez à l'unicode comme la norme, ou l'état idéal. Unicode n'est qu'un tableau de caractères. №65 est la capitale latine A. №937 est la capitale grecque oméga. Juste ça.

Pour qu'un ordinateur puisse stocker et/ou manipuler Unicode, il doit le coder en octets. Le codage le plus simple d'Unicode est UCS-4; chaque caractère occupe 4 octets et tous les ~ 1000000 caractères sont disponibles. Les 4 octets contiennent le numéro du caractère dans les tables Unicode sous la forme d'un entier sur 4 octets. Un autre encodage très utile est UTF-8, qui peut encoder n'importe quel caractère Unicode avec un à quatre octets. Mais il existe également des encodages limités, comme "latin1", qui incluent une gamme très limitée de caractères, principalement utilisés par les pays occidentaux. De tels encodages n'utilisent qu'un octet par caractère.

Fondamentalement, Unicode peut être encodé avec de nombreux encodages, et les chaînes encodées peuvent être décodées à Unicode. Le fait est que Unicode est arrivé assez tard, donc nous tous qui avons grandi en utilisant un jeu de caractères 8 bits avons appris trop tard que tout ce temps nous avons travaillé avec chaînes codées . L'encodage pourrait être ISO8859-1, ou windows CP437, ou CP850, ou, ou, ou, selon notre système par défaut.

Donc, lorsque, dans votre code source, vous entrez la chaîne "ajouter" Monitoring "à la liste" (et je pense que vous vouliez la chaîne "ajouter" Monitoring "à la liste", notez la deuxième citation), vous utilisez en fait déjà une chaîne encodé selon la page de code par défaut de votre système (par l'octet\x93 je suppose que vous utilisez la page de code Windows 1252, "Western"). Si vous voulez obtenir Unicode à partir de cela, vous devez décoder la chaîne du codage "cp1252".

Donc, ce que vous vouliez faire, c'était:

"add \x93Monitoring\x94 to list".decode("cp1252", "ignore")

Il est regrettable que Python 2.x inclut un .encode méthode pour les chaînes aussi; c'est une fonction pratique pour les encodages "spéciaux", comme ceux "Zip" ou "rot13" ou "base64", qui n'ont rien à voir avec Unicode.

Quoi qu'il en soit, tout ce que vous devez retenir pour vos conversions va-et-vient Unicode est:

  • une chaîne Unicode est encodée en une chaîne Python 2.x (en fait, une séquence d'octets)
  • une chaîne Python 2.x obtient décodée en une chaîne Unicode

Dans les deux cas, vous devez spécifier le codage qui sera utilisé.

Je ne suis pas très clair, j'ai sommeil, mais j'espère bien aider.

PS Une note humoristique: les Mayas n'avaient pas Unicode; les anciens Romains, les anciens Grecs, les anciens Égyptiens non plus. Ils avaient tous leurs propres "encodages" et avaient peu ou pas de respect pour les autres cultures. Toutes ces civilisations se sont effondrées en poussière. Pensez-y les gens! Faites en sorte que vos applications soient compatibles avec Unicode, pour le bien de l'humanité. :)

PS2 Merci de ne pas gâcher le message précédent en disant "Mais les chinois…". Si vous vous sentez enclin ou obligé de le faire, cependant, retardez-le en pensant que l'Unicode BMP est principalement peuplé d'idéogrammes chinois, l'ergo chinois est la base d'Unicode. Je peux continuer à inventer des scandaleux mensonges, tant que les gens développent des applications Unicode.

211
tzot

l'encodage est disponible pour les chaînes unicode, mais la chaîne que vous y avez ne semble pas unicode (essayez avec u'add\x93Monitoring\x93 to list ')

>>> u'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
'add \x93Monitoring\x93 to list '
4
rob

J'ai également écrit un long blog sur ce sujet:

Les tracas d'Unicode et continuer avec

0
Gregg Lind