unsupported error python python-2.7 chinese-locale

error - locale windows python



Cómo solucionarlo: “UnicodeDecodeError: el códec ''ascii'' no puede decodificar byte” (15)

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 blogs estáticos basados ​​en python, las publicaciones en chino pueden publicarse con éxito. Como esta aplicación: http://github.com/vrypan/bucket3 . En mi sitio http://bc3.brite.biz/ , la publicación china se puede publicar con éxito.


No utilice la respuesta aceptada ( sys.setdefaultencoding(''utf8'') )

Es un hack desagradable (hay una razón por la que tienes que usar reload ) que solo enmascara los problemas. Comprenda el problema, arregle la causa raíz y disfrute de Unicode zen. Consulte ¿Por qué NO debemos usar sys.setdefaultencoding ("utf-8") en un script py? para mas detalles

tl; dr / solución rápida

  • No decodifique / codifique willy nilly
  • No asuma que sus cadenas están codificadas en UTF-8
  • Intente convertir cadenas a cadenas Unicode lo antes posible en su código

Unicode Zen en Python 2.x - La versión larga

Sin ver la fuente, es difícil saber la causa raíz, por lo que tendré que hablar en general.

UnicodeDecodeError: ''ascii'' codec can''t decode byte generalmente ocurre cuando intenta convertir una str Python 2.x que contiene un ASCII a una cadena Unicode sin especificar la codificación de la cadena original.

En resumen, las cadenas Unicode son un tipo de cadena Python completamente independiente que no contiene ninguna codificación. Solo tienen códigos de puntos Unicode y, por lo tanto, pueden contener cualquier punto Unicode de todo el espectro. Las cadenas contienen texto codificado, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5, etc. Las cadenas se decodifican en Unicode y las Unicode 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 puerta de calidad al 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 saber la codificación de la cadena entrante, por lo que dependerán de usted para decodificar cadenas a cadenas Unicode antes de pasar a Markdown.

Las cadenas Unicode se pueden declarar en su código usando el prefijo u para cadenas. P.ej

>>> my_u = u''my ünicôdé strįng'' >>> type(my_u) <type ''unicode''>

Las 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 se llama explícitamente a unicode() .

Los siguientes escenarios causan excepciones de UnicodeDecodeError :

# Explicit conversion without encoding unicode(''€'') # New style format string into Unicode string # Python will try to convert value string to Unicode first u"The currency is: {}".format(''€'') # Old style format string into Unicode string # Python will try to convert value string to Unicode first u''The currency is: %s'' % ''€'' # Append string to Unicode # Python will try to convert string to Unicode first u''The currency is: '' + ''€''

Ejemplos

En el siguiente diagrama, puede ver cómo la palabra café se ha codificado en codificación "UTF-8" o "Cp1252" según el tipo de terminal. En ambos ejemplos, caf es 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 una coincidencia)). Se invoca la decode() correcta decode() y la conversión a un Unicode de Python es exitosa:

En este diagrama, decode() se llama con ascii (que es lo mismo que llamar a unicode() sin una codificación dada). Como ASCII no puede contener bytes mayores que 0x7F , esto generará una excepción UnicodeDecodeError :

El Sandwich De Unicode

Es una buena práctica formar un sándwich de Unicode en su código, donde decodifique todos los datos entrantes a cadenas de Unicode, trabaje con Unicodes y luego codifique a str s en el camino de salida. Esto le evita preocuparse por la codificación de cadenas en 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 una u . P.ej

u''Zürich''

Para permitir que Python descodifique 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:

# encoding: utf-8

Esto solo es necesario cuando no tiene ASCII en su código fuente .

Archivos

Por lo general, los datos que no son ASCII se reciben de un archivo. El módulo io proporciona un TextWrapper que decodifica su archivo sobre la marcha, utilizando una encoding dada. Debe usar la codificación correcta para el archivo, no se puede adivinar fácilmente. Por ejemplo, para un archivo UTF-8:

import io with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file: my_unicode_string = my_file.read()

my_unicode_string sería adecuado para pasar a Markdown. Si un UnicodeDecodeError de la línea read() , entonces probablemente ha usado el valor de codificación incorrecto.

Archivos CSV

El módulo CSV de Python 2.7 no admite caracteres no ASCII 😩. Sin embargo, hay ayuda disponible con https://pypi.python.org/pypi/backports.csv .

Úsalo como arriba, pero pasa el archivo abierto:

from backports import csv import io with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file: for row in csv.reader(my_file): yield row

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. Siempre use cadenas Unicode para consultas SQL.

MySQL

En la cadena de conexión agregar:

charset=''utf8'', use_unicode=True

P.ej

>>> db = MySQLdb.connect(host="localhost", user=''root'', passwd=''passwd'', db=''sandbox'', use_unicode=True, charset="utf8") PostgreSQL

Añadir:

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

HTTP

Las páginas web pueden codificarse en casi cualquier codificación. El encabezado de Content-type debe contener un campo de juego de charset para indicar la codificación. El contenido puede entonces decodificarse manualmente contra este valor. Como alternativa, Python-Requests devuelve Unicodes en response.text .

A mano

Si debe decodificar cadenas manualmente, simplemente puede hacer my_string.decode(encoding) , donde la encoding es la codificación adecuada. Los códecs compatibles con Python 2.x se proporcionan aquí: Codificaciones estándar . Nuevamente, 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 stdout. Python intenta configurar un codificador en la salida estándar para que los Unicodes estén codificados en la codificación de la consola. Por ejemplo, si la locale un shell de Linux es en_GB.UTF-8 , la salida se codificará como UTF-8 . En Windows, estará limitado a una página de códigos de 8 bits.

Una consola configurada incorrectamente, como una configuración regional dañada, puede provocar errores de impresión inesperados. PYTHONIOENCODING variable de entorno PYTHONIOENCODING puede forzar la codificación de la PYTHONIOENCODING .

Archivos

Al igual que la entrada, io.open se puede usar para convertir Unicodes de manera transparente en cadenas de bytes codificadas.

Base de datos

La misma configuración para la lectura permitirá escribir Unicodes directamente.

Python 3

Python 3 ya no es compatible con Unicode como Python 2.x, pero la str normal ahora es una cadena Unicode y la str antigua ahora es bytes .

La codificación predeterminada ahora es UTF-8, por lo que si .decode() una cadena de bytes sin dar una codificación, Python 3 usa la codificación UTF-8. Esto probablemente soluciona el 50% de los problemas de Unicode de las personas.

Además, open() opera en modo de texto por defecto, por lo que devuelve str decodificada (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.


Aquí está mi solución, simplemente añada la codificación. with open(file, encoding=''utf8'') as f

Y debido a que la lectura del archivo de guante llevará mucho tiempo, recomiendo el archivo de guante a un archivo de número. Cuando el tiempo de netx lea los pesos de incrustación, ahorrará tiempo.

import numpy as np from tqdm import tqdm def load_glove(file): """Loads GloVe vectors in numpy array. Args: file (str): a path to a glove file. Return: dict: a dict of numpy arrays. """ embeddings_index = {} with open(file, encoding=''utf8'') as f: for i, line in tqdm(enumerate(f)): values = line.split() word = ''''.join(values[:-300]) coefs = np.asarray(values[-300:], dtype=''float32'') embeddings_index[word] = coefs return embeddings_index # EMBEDDING_PATH = ''../embedding_weights/glove.840B.300d.txt'' EMBEDDING_PATH = ''glove.840B.300d.txt'' embeddings = load_glove(EMBEDDING_PATH) np.save(''glove_embeddings.npy'', embeddings)

Enlace completo: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227


Codificar convierte un objeto Unicode en un objeto de cadena. Creo que estás tratando de codificar un objeto de cadena. primero convierta su resultado en un objeto Unicode y luego codifique ese objeto Unicode en ''utf-8''. por ejemplo

result = yourFunction() result.decode().encode(''utf-8'')


Creo que lo mejor es convertir siempre a Unicode, pero esto es difícil de lograr porque en la práctica tendrías que revisar y convertir cada argumento en cada función y método que escribas que incluya algún tipo de procesamiento de cadenas.

Así que se me ocurrió el siguiente enfoque para garantizar unicodes o cadenas de bytes, desde cualquier entrada. En resumen, incluya y use las siguientes lambdas:

# guarantee unicode string _u = lambda t: t.decode(''UTF-8'', ''replace'') if isinstance(t, str) else t _uu = lambda *tt: tuple(_u(t) for t in tt) # guarantee byte string in UTF8 encoding _u8 = lambda t: t.encode(''UTF-8'', ''replace'') if isinstance(t, unicode) else t _uu8 = lambda *tt: tuple(_u8(t) for t in tt)

Ejemplos:

text=''Some string with codes > 127, like Zürich'' utext=u''Some string with codes > 127, like Zürich'' print "==> with _u, _uu" print _u(text), type(_u(text)) print _u(utext), type(_u(utext)) print _uu(text, utext), type(_uu(text, utext)) print "==> with u8, uu8" print _u8(text), type(_u8(text)) print _u8(utext), type(_u8(utext)) print _uu8(text, utext), type(_uu8(text, utext)) # with % formatting, always use _u() and _uu() print "Some unknown input %s" % _u(text) print "Multiple inputs %s, %s" % _uu(text, text) # but with string.format be sure to always work with unicode strings print u"Also works with formats: {}".format(_u(text)) print u"Also works with formats: {},{}".format(*_uu(text, text)) # ... or use _u8 and _uu8, because string.format expects byte strings print "Also works with formats: {}".format(_u8(text)) print "Also works with formats: {},{}".format(*_uu8(text, text))

Aquí hay un poco más de razonamiento sobre esto .


En algunos casos, cuando verifica su codificación predeterminada ( print sys.getdefaultencoding() ), devuelve que está usando ASCII. Si cambia a UTF-8, no funcionará, dependiendo del contenido de su variable. Encontré otra manera:

import sys reload(sys) sys.setdefaultencoding(''Cp1252'')


En resumen, para garantizar un manejo adecuado de Unicode en Python 2:

  • usar io.open para leer / escribir archivos
  • usar from __future__ import unicode_literals
  • configurar otras entradas / salidas de datos (por ejemplo, bases de datos, red) para usar Unicode
  • Si no puede configurar las salidas a utf-8, convierta su salida para print(text.encode(''ascii'', ''replace'').decode())

Para explicaciones, vea la respuesta detallada de @Alastair McCormack.


En un proyecto Django (1.9.10) / Python UnicodeDecodeError tengo frecuentes excepciones UnicodeDecodeError ; Principalmente cuando trato de alimentar cadenas Unicode para el registro. Hice una función auxiliar para que los objetos arbitrarios se formatearan básicamente a cadenas ASCII de 8 bits y reemplazando 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), funcionará:

def encode_for_logging(c, encoding=''ascii''): if isinstance(c, basestring): return c.encode(encoding, ''replace'') elif isinstance(c, Iterable): c_ = [] for v in c: c_.append(encode_for_logging(v, encoding)) return c_ else: return encode_for_logging(unicode(c)) `


Estaba buscando para resolver el siguiente mensaje de error:

unicodedecodeerror: el codec ''ascii'' no puede decodificar el byte 0xe2 en la posición 5454: ordinal no está en el rango (128)

Finalmente lo arreglé especificando ''codificación'':

f = open(''../glove/glove.6B.100d.txt'', encoding="utf-8")

Ojalá pudiera ayudarte también.


Este error ocurre principalmente porque su contexto requiere una cadena Unicode pero lo que se pasa es solo una cadena. antes de convertir en código, compruebe si la cadena ya está en Unicode, en cuyo caso obtendrá un TypeError: no se admite la descodificación de Unicode, ya que está intentando convertir en Unicode una cadena que ya está en Unicode. Verifíquelo antes de convertir como abajo:

if isinstance(input_string, str): input_string = unicode(input_string, ''utf-8'')

Añadiendo lo anterior, lo anterior no elimina los caracteres no compatibles. Solo cambia el tipo pero el non ascii permanece. Para eliminar los caracteres utiliza el siguiente,

if isinstance(input_string, str): input_string = input_string.decode(''ascii'', ''ignore'').encode(''ascii'') #note: this removes the character and encodes back to string. elif isinstance(input_string, unicode): input_string = input_string.encode(''ascii'', ''ignore'')


Este error se produce cuando hay algunos caracteres no ASCII en nuestra cadena y estamos realizando operaciones en esa cadena sin la decodificación adecuada. Esto me ayudó a resolver mi problema. Estoy leyendo un archivo CSV con las columnas ID, texto y decodificación de caracteres como sigue:

train_df = pd.read_csv("Example.csv") train_data = train_df.values for i in train_data: print("ID :" + i[0]) text = i[1].decode("utf-8",errors="ignore").strip().lower() print("Text: " + text)


Este es el clásico "problema de Unicode". Creo que explicar esto está más allá del alcance de una respuesta de para explicar completamente lo que está sucediendo.

Está bien explicado here .

En un breve resumen, 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) está fallando.

La presentación que te señalé proporciona consejos para evitar esto. Haga su código un "sándwich Unicode". En Python 2, el uso de "from __future__ import unicode_literals" ayuda.

Actualización: cómo se puede arreglar el código:

OK - en tu variable "fuente" tienes algunos bytes. De su pregunta no queda claro cómo llegaron allí. ¿Tal vez los lea 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. Necesitas decirle explícitamente qué es la codificación. ¡Esto significa que necesitas saber cuál es la codificación! Eso no siempre es fácil, y depende completamente de la procedencia de esta cadena. Podría experimentar con algunas codificaciones comunes, por ejemplo, UTF-8. Le dices a Unicode () la codificación como un segundo parámetro:

source = unicode(source, ''utf-8'')


Tengo el mismo problema con la cadena "PastelerÃa Mallorca" y resolví con:

unicode("Pastelería Mallorca", ''latin-1'')


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

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

En mi caso, funcionó para mí, en Python 2.7, supongo que esta asignación cambió "algo" en la representación interna de str , es decir, fuerza la decodificación correcta de la secuencia de bytes respaldada en la url y finalmente pone la cadena en un utf. 8 str con toda la magia en el lugar correcto. Unicode en Python es magia negra para mí. Esperanza útil


Tuve el mismo problema pero no funcionó para Python 3. Seguí esto y resolví mi problema:

enc = sys.getdefaultencoding() file = open(menu, "r", encoding = enc)

Debe configurar la codificación cuando esté leyendo / escribiendo el archivo.


Finalmente lo tengo:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py # encoding=utf8 import sys reload(sys) sys.setdefaultencoding(''utf8'')

Dejame revisar:

as3:~/ngokevin-site# python Python 2.7.6 (default, Dec 6 2013, 14:49:02) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> reload(sys) <module ''sys'' (built-in)> >>> sys.getdefaultencoding() ''utf8'' >>>

Lo anterior muestra que la codificación predeterminada de python es utf8 . Entonces el error ya no existe.