unidecode - unicode() python3
Python lanza UnicodeEncodeError aunque estoy haciendo str.decode(). ¿Por qué? (6)
Estás pasando una cadena que ya es unicode. Entonces, antes de que Python pueda invocar decode
en él, tiene que codificarlo, y lo hace de manera predeterminada utilizando la codificación ASCII.
Editar para agregar Depende de lo que quieras hacer. Si simplemente desea convertir una cadena Unicode con caracteres que no sean ASCII en una representación codificada en HTML, puede hacerlo en una sola llamada: text.encode(''ascii'', ''xmlcharrefreplace'')
.
Considera esta función:
def escape(text):
print repr(text)
escaped_chars = []
for c in text:
try:
c = c.decode(''ascii'')
except UnicodeDecodeError:
c = ''&{};''.format(htmlentitydefs.codepoint2name[ord(c)])
escaped_chars.append(c)
return ''''.join(escaped_chars)
Debería escapar de todos los caracteres no ascii por los correspondientes htmlentitydefs. Lamentablemente lanzamientos de pitón
UnicodeEncodeError: ''ascii'' codec can''t encode character u''/xe1'' in position 0: ordinal not in range(128)
cuando el text
variable contiene la cadena cuya repr()
es u''Tam/xe1s Horv/xe1th''
.
Pero, no uso str.encode()
. Solo uso str.decode()
. ¿Extraño algo?
Python tiene dos tipos de cadenas: cadenas de caracteres (el tipo unicode
) y cadenas de bytes (el tipo str
). El código que ha pegado funciona en byte-strings. Necesita una función similar para manejar cadenas de caracteres.
Tal vez esto:
def uescape(text):
print repr(text)
escaped_chars = []
for c in text:
if (ord(c) < 32) or (ord(c) > 126):
c = ''&{};''.format(htmlentitydefs.codepoint2name[ord(c)])
escaped_chars.append(c)
return ''''.join(escaped_chars)
Me pregunto si alguna de las funciones es realmente necesaria para ti. Si fuera yo, elegiría UTF-8 como la codificación de caracteres para el documento de resultados, procesaría el documento en forma de cadena de caracteres (sin preocuparse por las entidades) y realizaría un content.encode(''UTF-8'')
como el paso final antes de entregárselo al cliente. Dependiendo del marco de trabajo web de su elección, incluso podrá enviar cadenas de caracteres directamente a la API y hacer que descubra cómo establecer la codificación.
decode
una str
no tiene sentido.
Creo que puedes marcar ord(c)>127
Encontré solución en este sitio
reload(sys) sys.setdefaultencoding("latin-1") a = u''/xe1'' print str(a) # no exception
Es un informe de error engañoso que proviene de la forma en que python maneja el proceso de de / codificación. ¡Intentó decodificar una cadena ya decodificada por segunda vez y eso confunde la función de Python que toma represalias confundiéndolo a su vez! ;-) El proceso de codificación / decodificación se lleva a cabo hasta donde yo sé, por los codecs-módulo. Y en algún lugar ahí se encuentra el origen de estos engañosos mensajes de excepción.
Puede verificarlo usted mismo:
u''/x80''.encode(''ascii'')
o
u''/x80''.decode(''ascii'')
lanzará un error de codificación Unicode, donde
u''/x80''.encode(''utf8'')
no lo hará, pero
u''/x80''.decode(''utf8'')
otra vez lo hará!
Supongo que estás confundido por el significado de la codificación y la decodificación. Para decirlo simple:
decode encode
ByteString (ascii) --------> UNICODE ---------> ByteString (utf8)
codec codec
Pero ¿por qué hay un codec
argumento para el método de decode
? Bueno, la función subyacente no puede adivinar con qué códec se codificó ByteString, por lo que, como sugerencia, toma el codec
como argumento. Si no se proporciona, asume que quiere decir que se usa implícitamente sys.getdefaultencoding()
.
así que cuando usas c.decode(''ascii'')
a) tienes un ByteString (codificado) (es por eso que usas decodificación) b) quieres obtener un objeto de representación unicode (para eso utilizas la decodificación) yc ) el códec en el que se codifica ByteString es ascii.
Ver también: https://.com/a/370199/1107807
http://docs.python.org/howto/unicode.html
http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
http://www.stereoplex.com/blog/python-unicode-and-unicodedecodeerror
Esta respuesta siempre me funciona cuando tengo este problema:
def byteify(input):
''''''
Removes unicode encodings from the given input string.
''''''
if isinstance(input, dict):
return {byteify(key):byteify(value) for key,value in input.iteritems()}
elif isinstance(input, list):
return [byteify(element) for element in input]
elif isinstance(input, unicode):
return input.encode(''utf-8'')
else:
return input
de Cómo obtener objetos de cadena en lugar de Unicode de JSON en Python?