UnicodeDecodeError: le codec 'ascii' ne peut pas décoder l'octet 0xef en position 1

106

J'ai quelques problèmes en essayant d'encoder une chaîne en UTF-8. J'ai essayé de nombreuses choses, y compris l'utilisation de string.encode('utf-8')et unicode(string), mais j'obtiens l'erreur:

UnicodeDecodeError: le codec 'ascii' ne peut pas décoder l'octet 0xef en position 1: l'ordinal n'est pas dans la plage (128)

Ceci est ma chaîne:

(。・ω・。)ノ

Je ne vois pas ce qui ne va pas, aucune idée?

Edit: Le problème est que l'impression de la chaîne telle quelle ne s'affiche pas correctement. En outre, cette erreur lorsque j'essaye de le convertir:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
Markum
la source
C'est juste une chaîne normalement insérée. La même chose se produit lorsque j'essaie simplement de l'imprimer.
Markum
Je rencontre la même chose lors de l'installation de pip, et je le
répare à

Réponses:

70

Cela est dû au fait que l'encodage de votre terminal n'est pas réglé sur UTF-8. Voici mon terminal

$ echo $LANG
en_GB.UTF-8
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> 

Sur mon terminal, l'exemple fonctionne avec ce qui précède, mais si je supprime le LANGparamètre, cela ne fonctionnera pas

$ unset LANG
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
>>> 

Consultez la documentation de votre variante Linux pour découvrir comment rendre ce changement permanent.

Nick Craig-Wood
la source
1
Des paramètres régionaux manquants pourraient également être une raison. Pour les installer, exécutez sudo apt-get install language-pack-deou sudo locale-gen de_DE.UTF-8(pour les paramètres régionaux allemands).
Non le
Pour moi, la variable d'environnement manquante est LC_ALL, et la valeur la plus simple qui la corrigerait estC.UTF-8
Robin Winslow
24

essayer:

string.decode('utf-8')  # or:
unicode(string, 'utf-8')

Éditer:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')donne u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', ce qui est correct.

donc votre problème doit se trouver à un autre endroit, peut-être si vous essayez de faire quelque chose avec, il y a une conversion implicite en cours (peut-être imprimer, écrire dans un flux ...)

pour en dire plus, nous aurons besoin de voir du code.

mata
la source
Les deux reviennentUnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
Markum
'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
Markum
1
Tout ce que j'essaie de faire est d'imprimer la chaîne d'origine dans son format d'origine, mais j'obtiens (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum
4
le stringest encodé en utf8. si vous l'imprimez, il connecte simplement les octets au flux de sortie, et si votre terminal ne l'interprète pas comme utf8, vous vous retrouvez avec des déchets. avec decodevous le convertissez en unicode, puis vous pouvez encodeà nouveau le convertir en un encodage que votre terminal comprend.
mata
21

Mon +1 au commentaire de mata sur https://stackoverflow.com/a/10561979/1346705 et à la démonstration de Nick Craig-Wood. Vous avez correctement décodé la chaîne. Le problème vient de la printcommande car elle convertit la chaîne Unicode en codage de la console et la console n'est pas capable d'afficher la chaîne. Essayez d'écrire la chaîne dans un fichier et regardez le résultat en utilisant un éditeur décent qui prend en charge Unicode:

import codecs

s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
s1 = s.decode('utf-8')
f = codecs.open('out.txt', 'w', encoding='utf-8')
f.write(s1)
f.close()

Ensuite, vous verrez (。・ω・。)ノ.

pepr
la source
10

Si vous travaillez sur un hôte distant , regardez /etc/ssh/ssh_configsur votre PC local .

Lorsque ce fichier contient une ligne:

SendEnv LANG LC_*

commentez-le en ajoutant #en tête de ligne. Cela pourrait aider.

Avec cette ligne, sshenvoie les variables d'environnement liées à la langue de votre PC à l' hôte distant . Cela cause beaucoup de problèmes.

Tsutomu
la source
Merci! Ceux-ci ont résolu le problème que j'avais en installant des packages pip avec ansible et vagrant
Maritza Esparza
10

Essayez de définir le codage par défaut du système utf-8au début du script, de sorte que toutes les chaînes soient codées à l'aide de celui-ci.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Andrei Krasutski
la source
pourquoi avons-nous besoin du rechargement dans ce cas?
Fallingdog
Cela ne fonctionne pas dans Python 3 comme expliqué ici . Pour moi, la réponse de Tsutomu ci - dessous a fait l'affaire.
Piyush Goel
5

C'est bien d'utiliser le code ci-dessous en haut de votre script comme l'a suggéré Andrei Krasutski .

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Mais je vais vous suggérer d'ajouter également une # -*- coding: utf-8 -*ligne tout en haut du script.

L'omettre jette une erreur ci-dessous dans mon cas lorsque j'essaie d'exécuter basic.py.

$ python basic.py
  File "01_basic.py", line 14
SyntaxError: Non-ASCII character '\xd9' in file basic.py on line 14, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Ce qui suit est le code présent dans basic.pylequel jette l'erreur ci-dessus.

code avec erreur

from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Ensuite, j'ai ajouté la # -*- coding: utf-8 -*-ligne tout en haut et exécuté. Ça a marché.

code sans erreur

# -*- coding: utf-8 -*-
from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Merci.

hygull
la source
1
Utiliser #coding: utf-8plutôt que # -*- coding: utf-8 -*- cela est plus facile à retenir. Fonctionne directement avec Python PEP 263 - Définition des encodages de code source Python .
Andrei Krasutski
Merci pour la suggestion. Je vais essayer à ma fin et le mettre à jour dans la réponse.
hygull le
4

Aucun problème avec mon terminal. Les réponses ci-dessus m'ont aidé à chercher dans la bonne direction, mais cela n'a pas fonctionné pour moi jusqu'à ce que j'ajoute 'ignore':

fix_encoding = lambda s: s.decode('utf8', 'ignore')

Comme indiqué dans le commentaire ci-dessous, cela peut conduire à des résultats indésirables. OTOH, cela peut aussi faire assez bien l'affaire pour que les choses fonctionnent et vous ne vous souciez pas de perdre certains personnages.

kqw
la source
2
C'est faux, vous forcez votre fonction de codage lambda à ignorer le codage lui-même, ce qui signifie que vous perdez des caractères.
Maximiliano Rios
2
Cela a résolu mon problème, où je ne connaissais pas l'encodage d'origine et je ne me souciais pas de perdre certains caractères.
Edhowler
2

cela fonctionne pour ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales
wlredeye
la source
1

Il semble que votre chaîne soit encodée utf-8, alors quel est exactement le problème? Ou qu'essayez-vous de faire ici ..?

Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> s2 = u'(。・ω・。)ノ'
>>> s2 == s1
True
>>> s2
u'(\uff61\uff65\u03c9\uff65\uff61)\uff89'
wim
la source
En imprimant la chaîne d'origine telle (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ëquelle, je veux qu'elle l'encode correctement.
Markum
1

Dans mon cas, cela a été causé par l'enregistrement de mon fichier Unicode avec une "BOM". Pour résoudre cela, j'ai ouvert le fichier en utilisant BBEdit et j'ai fait un "Enregistrer sous ..." en choisissant l'encodage "Unicode (UTF-8)" et non ce qu'il était livré avec qui était "Unicode (UTF-8, avec BOM) "

user336828
la source
0

J'obtenais le même type d'erreur et j'ai constaté que la console n'est pas capable d'afficher la chaîne dans une autre langue. Par conséquent, j'ai apporté les modifications de code ci-dessous pour définir default_charset comme UTF-8.

data_head = [('\x81\xa1\x8fo\x89\xef\x82\xa2\x95\xdb\x8f\xd8\x90\xa7\x93x\x81\xcb3\x8c\x8e\x8cp\x91\xb1\x92\x86(\x81\x86\x81\xde\x81\x85)\x81\xa1\x8f\x89\x89\xf1\x88\xc8\x8aO\x81A\x82\xa8\x8b\xe0\x82\xcc\x90S\x94z\x82\xcd\x88\xea\x90\xd8\x95s\x97v\x81\xa1\x83}\x83b\x83v\x82\xcc\x82\xa8\x8e\x8e\x82\xb5\x95\xdb\x8c\xaf\x82\xc5\x8fo\x89\xef\x82\xa2\x8am\x92\xe8\x81\xa1', 'shift_jis')]
default_charset = 'UTF-8' #can also try 'ascii' or other unicode type
print ''.join([ unicode(lin[0], lin[1] or default_charset) for lin in data_head ])
Azam Khan
la source
-1

BOM, c'est si souvent BOM pour moi

vi le fichier, utilisez

:set nobomb

et enregistrez-le. Cela le résout presque toujours dans mon cas

Olly W
la source
-1

J'ai eu la même erreur, avec des URL contenant des caractères non-ascii (octets avec des valeurs> 128)

url = url.decode('utf8').encode('utf-8')

Cela a fonctionné pour moi, en Python 2.7, je suppose que cette affectation a changé `` quelque chose '' dans la strreprésentation interne - c'est-à-dire qu'elle force le bon décodage de la séquence d'octets sauvegardée urlet met finalement la chaîne dans un utf-8 str avec toute la magie dans au bon endroit. Unicode en Python est pour moi de la magie noire. Espoir utile

Fabiano Tarlao
la source
-2

je résous ce problème en changeant dans le fichier settings.py avec 'ENGINE': 'django.db.backends.mysql', n'utilisez pas 'ENGINE': 'mysql.connector.django',

user3787102
la source
@rayryeng Pouvez-vous expliquer la raison de votre modification? Il semble changer complètement le sens de ce que l'OP a écrit, de recommander un cadre particulier de recommander contre elle.
personne le
@AndrewMedico - Mes excuses. J'ai vu que ce message était très similaire à un autre, alors j'ai cru qu'ils étaient les mêmes. Je reviendrai.
rayryeng
-2

Convertissez simplement le texte explicitement en chaîne en utilisant str(). A travaillé pour moi.

Supratim Samantray
la source