as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!
¿Como arreglarlo?
En algunas otras aplicaciones de blog estáticas basadas en Python, las publicaciones chinas se pueden publicar con éxito. Como esta aplicación: http://github.com/vrypan/bucket3 . En mi sitio http://bc3.brite.biz/ , la publicación en chino se puede publicar con éxito.
python
python-2.7
chinese-locale
pescador
fuente
fuente
Respuestas:
tl; dr / solución rápida
reload
hacks rápidosUnicode Zen en Python 2.x - La versión larga
Sin ver la fuente, es difícil conocer la causa raíz, por lo que tendré que hablar en general.
UnicodeDecodeError: 'ascii' codec can't decode byte
generalmente ocurre cuando intenta convertir un Python 2.xstr
que contiene no ASCII a una cadena Unicode sin especificar la codificación de la cadena original.En resumen, las cadenas Unicode son un tipo completamente separado de cadena Python que no contiene ninguna codificación. Solo contienen códigos de punto Unicode y, por lo tanto, pueden contener cualquier punto Unicode de todo el espectro. Las cadenas contienen texto codificado, como UTF-8, UTF-16, ISO-8895-1, GBK, Big5, etc. Las cadenas se decodifican en Unicode y los Unicodes se codifican en cadenas . Los archivos y los datos de texto siempre se transfieren en cadenas codificadas.
Los autores del módulo Markdown probablemente usan
unicode()
(donde se lanza la excepción) como una puerta de calidad para el resto del código: convertirá ASCII o volverá a envolver las cadenas Unicodes existentes en una nueva cadena Unicode. Los autores de Markdown no pueden conocer la codificación de la cadena entrante, por lo que confiarán en usted para decodificar cadenas en cadenas Unicode antes de pasar a Markdown.Las cadenas Unicode se pueden declarar en su código utilizando el
u
prefijo a las cadenas. P.ejLas cadenas Unicode también pueden provenir de archivos, bases de datos y módulos de red. Cuando esto sucede, no necesita preocuparse por la codificación.
Gotchas
La conversión de
str
a Unicode puede ocurrir incluso cuando no llama explícitamenteunicode()
.Los siguientes escenarios causan
UnicodeDecodeError
excepciones:Ejemplos
En el siguiente diagrama, puede ver cómo
café
se ha codificado la palabra en codificación "UTF-8" o "Cp1252" dependiendo del tipo de terminal. En ambos ejemplos,caf
es solo ascii regular. En UTF-8,é
se codifica utilizando dos bytes. En "Cp1252", é es 0xE9 (que también es el valor del punto Unicode (no es coincidencia)). Sedecode()
invoca lo correcto y la conversión a Python Unicode es exitosa:En este diagrama,
decode()
se llama conascii
(que es lo mismo que llamarunicode()
sin una codificación dada). Como ASCII no puede contener bytes mayores que0x7F
, esto arrojará unaUnicodeDecodeError
excepción:El sandwich de Unicode
Es una buena práctica formar un sándwich Unicode en su código, donde decodifica todos los datos entrantes en cadenas Unicode, trabaja con Unicodes y luego codifica a
str
s al salir. Esto evita que se preocupe por la codificación de cadenas en el medio de su código.Entrada / Decodificación
Código fuente
Si necesita hornear no ASCII en su código fuente, simplemente cree cadenas Unicode prefijando la cadena con un
u
. P.ejPara permitir que Python decodifique su código fuente, deberá agregar un encabezado de codificación para que coincida con la codificación real de su archivo. Por ejemplo, si su archivo fue codificado como 'UTF-8', usaría:
Esto solo es necesario cuando tienes no ASCII en tu código fuente .
Archivos
Por lo general, los datos no ASCII se reciben de un archivo. El
io
módulo proporciona un TextWrapper que decodifica su archivo sobre la marcha, utilizando un determinadoencoding
. Debe usar la codificación correcta para el archivo; no se puede adivinar fácilmente. Por ejemplo, para un archivo UTF-8:my_unicode_string
entonces sería adecuado para pasar a Markdown. Si esUnicodeDecodeError
de laread()
línea, entonces probablemente haya usado el valor de codificación incorrecto.Archivos CSV
El módulo CSV Python 2.7 no admite caracteres que no sean ASCII 😩. Sin embargo, hay ayuda disponible con https://pypi.python.org/pypi/backports.csv .
Úselo como se indica arriba, pero pásele el archivo abierto:
Bases de datos
La mayoría de los controladores de bases de datos de Python pueden devolver datos en Unicode, pero generalmente requieren una pequeña configuración. Utilice siempre cadenas Unicode para consultas SQL.
MySQLEn la cadena de conexión agregue:
P.ej
PostgreSQLAñadir:
HTTP
Las páginas web se pueden codificar en casi cualquier codificación. El
Content-type
encabezado debe contener uncharset
campo para indicar la codificación. El contenido se puede decodificar manualmente contra este valor. Alternativamente, Python-Requests devuelve Unicodes enresponse.text
.A mano
Si debe decodificar cadenas manualmente, simplemente puede hacer
my_string.decode(encoding)
, dondeencoding
está la codificación adecuada. Los códecs compatibles con Python 2.x se proporcionan aquí: Codificaciones estándar . De nuevo, si obtienes,UnicodeDecodeError
entonces probablemente tienes la codificación incorrecta.La carne del sandwich
Trabaja con Unicodes como lo harías con strs normales.
Salida
stdout / impresión
print
escribe a través de la secuencia estándar. Python intenta configurar un codificador en stdout para que los Unicodes se codifiquen con la codificación de la consola. Por ejemplo, si un shell de Linuxlocale
esen_GB.UTF-8
, la salida se codificará enUTF-8
. En Windows, estará limitado a una página de códigos de 8 bits.Una consola configurada incorrectamente, como una configuración regional corrupta, puede provocar errores de impresión inesperados.
PYTHONIOENCODING
La variable de entorno puede forzar la codificación para stdout.Archivos
Al igual que la entrada,
io.open
se puede usar para convertir de manera transparente Unicodes en cadenas de bytes codificadas.Base de datos
La misma configuración para la lectura permitirá que los Unicodes se escriban directamente.
Python 3
Python 3 no es más capaz de Unicode que Python 2.x, sin embargo, está un poco menos confundido sobre el tema. Por ejemplo, el regular
str
ahora es una cadena Unicode y el antiguostr
ahorabytes
.La codificación predeterminada es UTF-8, por lo que si
.decode()
usa una cadena de bytes sin proporcionar una codificación, Python 3 usa la codificación UTF-8. Esto probablemente soluciona el 50% de los problemas Unicode de las personas.Además,
open()
opera en modo de texto por defecto, por lo que devuelve decodificadostr
(Unicode). La codificación se deriva de su configuración regional, que tiende a ser UTF-8 en sistemas Un * x o una página de códigos de 8 bits, como windows-1251, en cuadros de Windows.Por qué no deberías usar
sys.setdefaultencoding('utf8')
Es un truco desagradable (hay una razón que debe usar
reload
) que solo enmascarará problemas y dificultará su migración a Python 3.x. Comprenda el problema, solucione la causa raíz y disfrute del zen Unicode. Consulte ¿Por qué NO deberíamos usar sys.setdefaultencoding ("utf-8") en un script py? para mas detallesfuente
io.open
para leer / escribir archivos, usarfrom __future__ import unicode_literals
, configurar otras entradas / salidas de datos (por ejemplo, bases de datos) para usar Unicode.PYTHONIOENCODING=utf-8
. Si eso no lo soluciona, deberá comunicarse con el autor del script para corregir su código.Finalmente lo tengo:
Dejame revisar:
Lo anterior muestra que la codificación predeterminada de python es
utf8
. Entonces el error ya no existe.fuente
str
, por lo que no está atrasado allí. En Python 2.x, Unicode estaba en un estado de transición, por lo que habría sido peligroso asumir una codificación al convertir bytes a Unicodes. Por lo tanto, la codificación predeterminada de Py2 de ASCII fue una elección deliberada y por qué cambiar la codificación predeterminada requiere el truco deliberado de la recargasys
. La forma correcta de desterrar los errores de codificación en Py2 es decodificar y codificar de forma inequívoca (byte) cadenas en Unicode, cuando las conversiones son necesarias, no solo asumir que las cadenas están codificadas en UTF-8.Este es el clásico "problema unicode". Creo que explicar esto está más allá del alcance de una respuesta de StackOverflow para explicar completamente lo que está sucediendo.
Está bien explicado aquí .
En un resumen muy breve, ha pasado algo que se interpreta como una cadena de bytes a algo que necesita decodificarlo en caracteres Unicode, pero el códec predeterminado (ascii) falla.
La presentación que te señalé proporciona consejos para evitar esto. Convierta su código en un "sandwich unicode". En Python 2, el uso de
from __future__ import unicode_literals
ayudas.Actualización: cómo se puede arreglar el código:
OK - en tu variable "fuente" tienes algunos bytes. No está claro por su pregunta cómo llegaron allí, ¿tal vez los leyó de un formulario web? En cualquier caso, no están codificados con ascii, pero python está tratando de convertirlos a unicode suponiendo que lo estén. Necesita decirle explícitamente cuál es la codificación. ¡Esto significa que necesita saber cuál es la codificación! Eso no siempre es fácil, y depende completamente de dónde vino esta cadena. Podría experimentar con algunas codificaciones comunes, por ejemplo, UTF-8. Le dice a unicode () la codificación como un segundo parámetro:
fuente
currentFile = open(filename, 'rt', encoding='latin1')
ocurrentFile = open(filename, 'rt', encoding='utf-8')
- vea aquí: stackoverflow.com/a/23917799/2047442En algunos casos, cuando verifica su codificación predeterminada (
print sys.getdefaultencoding()
), devuelve que está utilizando ASCII. Si cambia a UTF-8, no funciona, dependiendo del contenido de su variable. Encontré otra forma:fuente
reload(sys)
se usa por esa razón en particular.Estaba buscando resolver el siguiente mensaje de error:
Finalmente lo solucioné especificando 'codificación':
Ojalá pudiera ayudarte también.
fuente
Causa de este error: input_string debe ser unicode pero se le dio str
Causa de este error: tratando de convertir unicode input_string en unicode
Entonces, primero verifique que su input_string sea
str
y conviértalo a unicode si es necesario:En segundo lugar, lo anterior solo cambia el tipo pero no elimina los caracteres que no son ascii. Si desea eliminar caracteres que no sean ascii:
fuente
Creo que lo mejor es convertir siempre a Unicode, pero esto es difícil de lograr porque en la práctica tendrías que verificar y convertir cada argumento a cada función y método que escribas que incluya alguna forma de procesamiento de cadenas.
Así que se me ocurrió el siguiente enfoque para garantizar cadenas unicodes o de bytes, desde cualquier entrada. En resumen, incluya y use las siguientes lambdas:
Ejemplos:
Aquí hay más razonamientos sobre esto .
fuente
print unicode(u'Zürich', encoding="UTF-8")
y luego se queja "Pero sorprendentemente no puede codificar unicode ext en UTF8".unicode()
no codifica; decodifica y no puedes decodificar un Unicode, ¡ya está decodificado!Para resolver esto a nivel de sistema operativo en una instalación de Ubuntu, verifique lo siguiente:
Si lo consigues
en vez de
luego establece
LC_CTYPE
yLC_ALL
así:fuente
Codificar convierte un objeto Unicode en un objeto de cadena. Creo que estás intentando codificar un objeto de cadena. primero convierta su resultado en objeto unicode y luego codifique ese objeto unicode en 'utf-8'. por ejemplo
fuente
Tuve el mismo problema pero no funcionó para Python 3. Seguí esto y resolvió mi problema:
Debe configurar la codificación cuando está leyendo / escribiendo el archivo.
fuente
Obtuve el mismo error y esto resolvió mi error. ¡Gracias! Python 2 y Python 3 que difieren en el manejo Unicode están haciendo que los archivos encurtidos sean bastante incompatibles para cargar. Entonces use el argumento de codificación de python pickle. El enlace a continuación me ayudó a resolver un problema similar cuando intentaba abrir datos encurtidos de mi python 3.7, mientras que mi archivo se guardó originalmente en la versión python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Copié la función load_pickle en mi script y llamé load_pickle (pickle_file) mientras cargaba mi input_data así:
La función load_pickle está aquí:
fuente
load_pickle
función en su respuesta.Esto funcionó para mí:
fuente
En resumen, para garantizar el manejo adecuado de Unicode en Python 2:
io.open
para leer / escribir archivosfrom __future__ import unicode_literals
print(text.encode('ascii', 'replace').decode())
Para explicaciones, consulte la respuesta detallada de @Alastair McCormack .
fuente
io.open(path, 'r', encoding='utf-8')
para leer archivos codificados con utf-8.Tuve el mismo error, con URL que contienen caracteres no ascii (bytes con valores> 128), mi solución:
Nota: utf-8, utf8 son simplemente alias. Usar solo 'utf8' o 'utf-8' debería funcionar de la misma manera
En mi caso, funcionó para mí, en Python 2.7, supongo que esta asignación cambió 'algo' en la
str
representación interna, es decir, fuerza la decodificación correcta de la secuencia de bytes respaldadaurl
y finalmente coloca la cadena en un utf-8str
con Toda la magia en el lugar correcto. Unicode en Python es magia negra para mí. Espero útilfuente
Tuve el mismo problema con la cadena "Pastelería Mallorca" y resolví con:
fuente
En un proyecto Django (1.9.10) / Python 2.7.5 tengo
``UnicodeDecodeError
excepciones frecuentes ; principalmente cuando intento alimentar cadenas unicode al registro. Hice una función auxiliar para que los objetos arbitrarios se formateen básicamente en cadenas ascii de 8 bits y reemplace cualquier carácter que no esté en la tabla a '?'. Creo que no es la mejor solución, pero como la codificación predeterminada es ascii (y no quiero cambiarla) lo hará:fuente
Este error ocurre cuando hay algunos caracteres no ASCII en nuestra cadena y estamos realizando cualquier operación en esa cadena sin la decodificación adecuada. Esto me ayudó a resolver mi problema. Estoy leyendo un archivo CSV con ID de columnas, texto y caracteres de decodificación como se muestra a continuación:
fuente
Aquí está mi solución, solo agregue la codificación.
with open(file, encoding='utf8') as f
Y debido a que leer el archivo de guantes llevará mucho tiempo, recomiendo el archivo de guantes a un archivo numpy. Cuando netx time lea los pesos de incrustación, le ahorrará tiempo.
Enlace general: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
fuente
Especifique: # encoding = utf-8 en la parte superior de su archivo Python, debería solucionar el problema
fuente