bytes - Python: el códec ''ascii'' no puede decodificar el byte
python decode (6)
Estoy realmente confundido. Intenté codificar pero el error decía can''t decode...
>>> "你好".encode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: ''ascii'' codec can''t decode byte 0xe4 in position 0: ordinal not in range(128)
Sé cómo evitar el error con el prefijo "u" en la cadena. Me pregunto por qué el error es "no se puede decodificar" cuando se llamó a la codificación. ¿Qué está haciendo Python bajo el capó?
En caso de que esté tratando con Unicode, a veces, en lugar de encode(''utf-8'')
, también puede intentar ignorar los caracteres especiales, por ej.
"你好".encode(''ascii'',''ignore'')
o como something.decode(''unicode_escape'').encode(''ascii'',''ignore'')
como se sugiere aquí .
No es particularmente útil en este ejemplo, pero puede funcionar mejor en otros escenarios cuando no es posible convertir algunos caracteres especiales.
Alternativamente, puede considerar reemplazar un personaje en particular utilizando replace()
.
Si usa Python <3, tendrá que decirle al intérprete que su literal de cadena es Unicode prefijándolo con u
:
Python 2.7.2 (default, Jan 14 2012, 23:14:09)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> "你好".encode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: ''ascii'' codec can''t decode byte 0xe4 in position 0: ordinal not in range(128)
>>> u"你好".encode("utf8")
''/xe4/xbd/xa0/xe5/xa5/xbd''
Lectura adicional : CÓMO de Unicode .
u"你好".encode(''utf8'')
para codificar una cadena Unicode. Pero si quieres representar "你好"
, debes decodificarlo. Al igual que:
"你好".decode("utf8")
Obtendrás lo que quieres. Tal vez deberías aprender más sobre codificar y decodificar.
Codifique siempre desde unicode a bytes.
En esta dirección, puedes elegir la codificación .
>>> u"你好".encode("utf8")
''/xe4/xbd/xa0/xe5/xa5/xbd''
>>> print _
你好
La otra forma es decodificar desde bytes a unicode.
En esta dirección, debes saber cuál es la codificación .
>>> bytes = ''/xe4/xbd/xa0/xe5/xa5/xbd''
>>> print bytes
你好
>>> bytes.decode(''utf-8'')
u''/u4f60/u597d''
>>> print _
你好
Este punto no puede enfatizarse lo suficiente. Si quieres evitar jugar unicode "whack-a-mole", es importante entender lo que está pasando en el nivel de datos. Aquí se explica de otra manera:
- Ya se decodificó un objeto Unicode, nunca querrá invocar
decode
en él. - Un objeto de cadena de bytes ya está codificado, nunca desea invocar
encode
en él.
Ahora, al ver .encode
en una cadena de bytes, Python 2 primero intenta convertirlo implícitamente a texto (un objeto unicode
). Del mismo modo, al ver .decode
en una cadena Unicode, Python 2 intenta convertirlo a bytes (un objeto str
) implícitamente.
Estas conversiones implícitas son la razón por la que puede obtener el Error
Decode
Unicode
cuando ha llamado a la encode
. Es porque la codificación generalmente acepta un parámetro de tipo unicode
; cuando se recibe un parámetro str
, hay una descodificación implícita en un objeto de tipo unicode
antes de volver a codificarlo con otra codificación. Esta conversión elige un decodificador "ascii" predeterminado † , que le proporciona el error de decodificación dentro de un codificador.
De hecho, en Python 3 los métodos str.decode
y bytes.encode
ni siquiera existen. Su eliminación fue un intento [controvertido] de evitar esta confusión común.
† ... o cualquiera que sea la codificación de las sys.getdefaultencoding()
; generalmente esto es ''ascii''
Puedes intentar esto
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
O
También puedes intentar seguir
Agregue la siguiente línea en la parte superior de su archivo .py.
# -*- coding: utf-8 -*-
"你好".encode(''utf-8'')
encode
convierte un objeto Unicode en un objeto de string
. Pero aquí lo has invocado en un objeto de string
(porque no tienes el u). Entonces, python tiene que convertir la string
a un objeto unicode
primero. Entonces hace el equivalente de
"你好".decode().encode(''utf-8'')
Pero la decodificación falla porque la cadena no es válida como ascii. Es por eso que obtienes una queja por no poder decodificar.