UnicodeDecodeError: el códec 'ascii' no puede decodificar el byte 0xef en la posición 1


106

Tengo algunos problemas al intentar codificar una cadena en UTF-8. He intentado varias cosas, incluido el uso de string.encode('utf-8')y unicode(string), pero aparece el error:

UnicodeDecodeError: el códec 'ascii' no puede decodificar el byte 0xef en la posición 1: ordinal no está en el rango (128)

Esta es mi cadena:

(。・ω・。)ノ

No veo qué va mal, ¿alguna idea?

Editar: El problema es que la impresión de la cadena tal como está no se muestra correctamente. Además, este error cuando intento convertirlo:

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)

Es solo una cadena insertada normalmente. Lo mismo sucede cuando intento imprimirlo.
Markum

Encuentro lo mismo cuando pip install, y lo soluciono desde aquí: [instalar algunos devel] [1] [1]: stackoverflow.com/questions/17931726/…
BollMose

Respuestas:


70

Esto tiene que ver con la codificación de su terminal que no está configurada en UTF-8. Aquí está mi 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
(。・ω・。)ノ
>>> 

En mi terminal, el ejemplo funciona con lo anterior, pero si me deshago de la LANGconfiguración, no funcionará

$ 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)
>>> 

Consulte los documentos de su variante de Linux para descubrir cómo hacer que este cambio sea permanente.


1
La falta de lugares también podría ser una razón. Para instalarlos, ejecute sudo apt-get install language-pack-deo sudo locale-gen de_DE.UTF-8(para configuraciones regionales alemanas).
No

Para mí, la variable de entorno que falta es LC_ALL, y el valor más simple que la solucionaría esC.UTF-8
Robin Winslow

24

tratar:

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

editar:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')da u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', lo cual es correcto.

por lo que su problema debe estar en algún otro lugar, posiblemente si intenta hacer algo con él donde hay una conversión implícita (podría estar imprimiendo, escribiendo en una secuencia ...)

para decir más, necesitaremos ver un código.


Ambos regresanUnicodeEncodeError: '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
Todo lo que intento hacer es imprimir la cadena original en su formato original, pero obtengo (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum

4
el stringes utf8-codificado. si lo imprime, simplemente conecta los bytes al flujo de salida, y si su terminal no lo interpreta como utf8, termina con basura. con decodelo convierte a Unicode, luego puede encodevolver a codificarlo con su terminal.
mata

21

Mi +1 al comentario de mata en https://stackoverflow.com/a/10561979/1346705 y a la demostración de Nick Craig-Wood. Ha decodificado la cadena correctamente. El problema está en el printcomando, ya que convierte la cadena Unicode en la codificación de la consola y la consola no puede mostrar la cadena. Intente escribir la cadena en un archivo y observe el resultado con un editor decente que admita 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()

Entonces lo verás (。・ω・。)ノ.


10

Si está trabajando en un host remoto , mire en /etc/ssh/ssh_configsu PC local .

Cuando este archivo contiene una línea:

SendEnv LANG LC_*

coméntelo agregando #al comienzo de la línea. Podría ayudar.

Con esta línea, sshenvía variables de entorno relacionadas con el idioma de su PC al host remoto . Causa muchos problemas.


¡Gracias! Esto resolvió el problema que tenía al instalar paquetes pip con ansible y vagrant
Maritza Esparza


5

Está bien usar el siguiente código en la parte superior de su script como sugirió Andrei Krasutski .

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

Pero te sugiero que también agregues # -*- coding: utf-8 -* línea en la parte superior del guión.

Omitirlo arroja el siguiente error en mi caso cuando intento ejecutar 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

El siguiente es el código presente en basic.py que arroja el error anterior.

código con error

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)

Entonces agregué # -*- coding: utf-8 -*- línea en la parte superior y ejecuté. Funcionó.

código sin error

# -*- 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)

Gracias.


1
Usar en #coding: utf-8lugar de # -*- coding: utf-8 -*- esto es más fácil de recordar. Funciona de inmediato con Python PEP 263 - Definición de codificaciones de código fuente de Python .
Andrei Krasutski

Gracias por la sugerencia. Lo probaré al final y lo actualizaré en la respuesta.
Hygull

4

No hay problemas con mi terminal. Las respuestas anteriores me ayudaron a buscar en las direcciones correctas, pero no me funcionó hasta que agregué 'ignore':

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

Como se indica en el comentario a continuación, esto puede dar lugar a resultados no deseados. OTOH también puede hacer el truco lo suficientemente bien como para que las cosas funcionen y no te preocupes por perder algunos personajes.


2
Esto está mal, está obligando a su función lambda de codificación a ignorar la codificación en sí, lo que significa que está perdiendo caracteres.
Maximiliano Rios

2
Esto resolvió mi problema, donde no conocía la codificación original y no me importaba perder algunos caracteres.
Edhowler

2

esto funciona para ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales

1

Parece que su cadena está codificada utf-8, entonces, ¿cuál es exactamente el problema? ¿O qué intentas hacer aquí ...?

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'

Al imprimir la cadena original tal como se muestra (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, quiero que se codifique correctamente.
Markum

1

En mi caso, fue causado porque mi archivo Unicode se guardó con una "BOM". Para resolver esto, abrí el archivo usando BBEdit e hice un "Guardar como ..." eligiendo para codificar "Unicode (UTF-8)" y no lo que venía con "Unicode (UTF-8, con BOM)" "


0

Recibí el mismo tipo de error y descubrí que la consola no es capaz de mostrar la cadena en otro idioma. Por lo tanto, hice los siguientes cambios en el código para establecer default_charset como 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 ])


-1

BOM, a menudo es BOM para mí

vi el archivo, use

:set nobomb

y guárdalo. Eso casi siempre lo arregla en mi caso


-1

Tuve el mismo error, con URL que contienen caracteres no ascii (bytes con valores> 128)

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

Funcionó para mí, en Python 2.7, supongo que esta asignación cambió 'algo' en la strrepresentación interna, es decir, fuerza la decodificación correcta de la secuencia de bytes respaldada urly finalmente coloca la cadena en un utf-8 str con toda la magia en el lugar correcto. Unicode en Python es magia negra para mí. Espero útil


-2

resuelvo ese problema cambiando en el archivo settings.py con 'ENGINE': 'django.db.backends.mysql', no use 'ENGINE': 'mysql.connector.django',


@rayryeng ¿Podrías explicar el motivo de tu edición? Parece cambiar completamente el significado de lo que escribió el OP, de recomendar una configuración en particular a recomendar en contra .
nadie

@AndrewMedico - Mis disculpas. Vi que este post era muy parecido a otro así que creí que eran iguales. Volveré atrás.
rayryeng

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.