web-dev-qa-db-fra.com

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

J'ai quelques problèmes à essayer de coder une chaîne en UTF-8. J'ai essayé de nombreuses choses, notamment en utilisant string.encode('utf-8') et unicode(string), mais j'obtiens l'erreur suivante:

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 en tant que telle ne s'affiche pas correctement. En outre, cette erreur lorsque j'essaie 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)
94
Markum

Ceci est dû au fait que l'encodage de votre terminal n'est pas défini 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 paramètre LANG, 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 savoir comment rendre cette modification permanente.

69
Nick Craig-Wood

essayer:

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

modifier:

'(\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.

votre problème doit donc se trouver ailleurs, peut-être si vous essayez de faire quelque chose si une conversion implicite est en cours (impression, écriture dans un flux, etc.).

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

23
mata

Mon +1 au commentaire de mata à https://stackoverflow.com/a/10561979/1346705 et à la démonstration de Nick Craig-Wood. Vous avez décodé la chaîne correctement. Le problème concerne la commande print car elle convertit la chaîne Unicode en codage de la console et la console n'est pas en mesure d'afficher la chaîne. Essayez d'écrire la chaîne dans un fichier et regardez le résultat en utilisant un éditeur correct qui supporte 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 (。・ω・。)ノ.

20
pepr

Si vous travaillez sur un hôte distant, consultez /etc/ssh/ssh_config sur votre ordinateur local.

Quand ce fichier contient une ligne:

SendEnv LANG LC_*

commentez-le en ajoutant # en début de ligne. Cela pourrait aider.

Avec cette ligne, ssh envoie les variables d’environnement de votre PC relatives à la langue à l’hôte remote. Cela cause beaucoup de problèmes.

8
Tsutomu

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

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
7
Andrei Krasutski

Pas de problèmes avec mon terminal. Les réponses ci-dessus m'ont aidé à chercher dans la bonne direction, mais cela n'a pas fonctionné jusqu'à ce que j'ai ajouté 'ignore':

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

Comme indiqué dans le commentaire ci-dessous, cela peut entraîner des résultats non souhaités. OTOH peut aussi assez bien faire l'affaire pour que les choses fonctionnent et vous ne vous souciez pas de perdre certains personnages.

4
guaka

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

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

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

L'omettre génère 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.py qui renvoie 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 __== '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Puis j'ai ajouté la ligne # -*- coding: utf-8 -*- 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 __== '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Merci.

2
hygull

Il semble que votre chaîne soit codée en utf-8, alors quel est 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'
1
wim

Dans mon cas, cela était dû au fait que mon fichier Unicode était enregistré avec une "BOM". Pour résoudre ce problème, j'ai ouvert le fichier à l'aide de BBEdit et j'ai effectué une opération "Enregistrer sous ..." en sélectionnant le codage "Unicode (UTF-8)" et non ce qu'il était livré avec "Unicode (UTF-8, avec nomenclature) "

1
user336828

cela fonctionne pour Ubuntu 15.10:

Sudo locale-gen "en_US.UTF-8"
Sudo dpkg-reconfigure locales
1
wlredeye

BOM, c'est souvent BOM pour moi

vi le fichier, utilisez

:set nobomb

et enregistrez-le. Cela le corrige presque toujours dans mon cas

0
Olly W

Je recevais 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 ])
0
Azam Khan