web-dev-qa-db-fra.com

Python ASCII et erreur de décodage Unicode

J'ai eu cette très frustrante erreur lors de l'insertion d'une certaine chaîne dans ma base de données. Il a dit quelque chose comme:

Python ne peut pas décoder les caractères octets, s'attendant à unicode " 

Après de nombreuses recherches, j'ai compris que je pouvais surmonter cette erreur en encodant ma chaîne dans Unicode . J'essaie de le faire en décodant d'abord la chaîne puis en l'encodant au format UTF-8 . Comme:

string = string.encode("utf8")

Et j'obtiens l'erreur suivante:

'ascii' codec can't decode byte 0xe3 in position 6: ordinal not in range(128)

Je suis en train de mourir avec cette erreur! Comment je le répare?

14
Amitash

EDIT: Comme vous pouvez le voir dans les votes négatifs, ce n’est pas la meilleure façon de le faire. Vous trouverez ci-dessous une excellente réponse vivement recommandée. Si vous recherchez une bonne solution, utilisez-la. Ceci est une solution bidon qui ne sera pas gentil avec vous plus tard.

Je ressens votre douleur, j'ai eu beaucoup de problèmes avec la même erreur. Le moyen le plus simple que j'ai résolu (et ce n'est peut-être pas le meilleur, et cela dépend de votre application) est de convertir les éléments en unicode et d'ignorer les erreurs. Voici un exemple tiré de Unicode HOWTO - Documentation Python v2.7.3

>>> unicode('\x80abc', errors='strict')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
                    ordinal not in range(128)
>>> unicode('\x80abc', errors='replace')
u'\ufffdabc'
>>> unicode('\x80abc', errors='ignore')
u'abc'

Même si cette méthode n’est peut-être pas la plus pratique, c’est une méthode qui a fonctionné pour moi.

MODIFIER:

Quelques personnes dans les commentaires ont mentionné qu'il s'agissait d'une mauvaise idée, même si le demandeur avait accepté la réponse. Ce n'est PAS une bonne idée, cela va tout gâcher si vous avez affaire à des personnages européens et accentués. Cependant, vous pouvez l'utiliser si ce n'est PAS un code de niveau de production, s'il s'agit d'un projet personnel sur lequel vous travaillez et qu'il vous faut une solution rapide pour que les choses bougent. Vous devrez éventuellement y remédier avec les bonnes méthodes, qui sont mentionnées dans les réponses ci-dessous.

4
Karthik Rangarajan

Vous devez adopter une approche disciplinée. Unicode pragmatique, ou comment puis-je arrêter la douleur? a tout ce dont vous avez besoin.

Si vous obtenez cette erreur sur cette ligne de code, le problème est que string est une chaîne d'octets et que Python 2 tente implicitement de la décoder en Unicode pour vous. Mais ce n'est pas pur ascii. Vous devez connaître le codage et le décoder correctement.

49
Ned Batchelder

La méthode encode doit être utilisée sur les objets unicode pour les convertir en un objet str avec un codage donné. La méthode decode doit être utilisée sur les objets str d’un codage donné pour les convertir en objets unicode.

Je suppose que votre base de données stocke des chaînes en UTF-8. Ainsi, lorsque vous obtenez des chaînes de la base de données, convertissez-les en objets unicode en effectuant str.decode('utf-8'). N'utilisez ensuite que des objets unicode dans votre programme python (les littéraux sont définis avec u'unicode string'). Et juste avant de les stocker dans votre base de données, convertissez-les en objets str avec uni.encode('utf-8').

12
Sylvain Defresne

Le point de code 0xE3 est un "a" avec un tilde en Unicode. Votre chaîne d'origine est probablement déjà en UTF-8, vous ne pouvez donc pas la décoder à l'aide du jeu de caractères ASCII par défaut.

2
Silas Ray

string in python 2.7 est une chaîne ecodée (principalement codée dans ASCII) mais pas une chaîne de caractères ou unicode.

Donc, quand vous faites string.encode ('un certain encodage'), vous encodez réellement une chaîne encodée (en utilisant un encodage)

Python doit d’abord décoder cette chaîne en utilisant l’encodage par défaut (ASCII en python 2.7), puis il encodera plus avant . Votre chaîne n’est pas encodée dans ASCII mais par un autre encodage (UTF8, LATIN-1 ..). Ainsi, lorsque python essaie de décoder cela en utilisant ASCII, il génère une erreur car le codec ASCII ne peut décoder quelques caractères de votre chaîne donnée qui se trouvent hors de la plage ASCII (0 - 127)

#to encode above given string, first decode that using some encoding
decoded_string = string.decode('utf8')
#now encode that decoded string
decoded_string.encode('utf8')
0
keshav