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)
Markum
fuente
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.

Nick Craig-Wood
fuente
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.

mata
fuente
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 (。・ω・。)ノ.

pepr
fuente
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.

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

Intente configurar la codificación predeterminada del sistema como utf-8al comienzo del script, de modo que todas las cadenas se codifiquen con eso.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Andrei Krasutski
fuente
¿Por qué necesitamos la recarga en este caso?
Fallingdog
Esto no funciona en Python 3 como se explica aquí . Para mí, la respuesta de Tsutomu a continuación funcionó.
Piyush Goel
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.

higull
fuente
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.

kqw
fuente
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
wlredeye
fuente
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'
wim
fuente
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)" "

user336828
fuente
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 ])
Azam Khan
fuente
-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

Olly W
fuente
-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

Fabiano Tarlao
fuente
-2

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

usuario3787102
fuente
@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
-2

Simplemente convierta el texto explícitamente en cadena usando str(). Trabajó para mi.

Supratim Samantray
fuente