python - UnicodeEncodeError: el codec ''ascii'' no puede codificar el carácter en la posición 0: ordinal no está en el rango(128)
encoding python-3.2 (4)
Cuando Python imprime y genera, se codifica automáticamente en el medio de destino. Si es un archivo, se usará UTF-8 como predeterminado y todos estarán contentos, pero si es un terminal, Python descubrirá la codificación que está usando el terminal e intentará codificar la salida usando ese.
Esto significa que si su terminal está utilizando ascii
como codificación, Python está tratando de codificar scissor
a ascii. Por supuesto, ascii no lo admite, por lo que se obtiene un error de decodificación de Unicode.
Es por esto que siempre tienes que codificar explícitamente tu salida . Explicito es mejor que recordatorio implícito? Para arreglar tu código puedes hacer:
import sys
sys.stdout.buffer.write(chr(9986).encode(''utf8''))
Esto parece un poco hacker. También puede configurar PYTHONIOENCODING = utf-8 antes de ejecutar el script. Estoy incómodo con ambas soluciones. Probablemente tu consola no sea compatible con utf-8 y ves tonterías. Pero tu programa se estará comportando correctamente.
Lo que recomiendo encarecidamente si definitivamente necesita mostrar el resultado correcto en su consola es configurar la consola para que use otra codificación, una que admita el carácter de scissor
. (utf-8 quizás). En Linux, eso se puede lograr haciendo: export lang=UTF_8
. En Windows cambias la página de códigos de la consola con chcp
. Solo averigüe cómo configurar utf8 en la suya y en mi humilde opinión, esa será la mejor solución.
print
y sys.stdout.write
porque son básicamente lo mismo. Con respecto a tu código, la forma hacker sería así: sys.stdout.buffer.write(("|/t "+ chr(9986) +" PySnipt''d " + chr(9986)+" /t|").encode(''utf8''))
Le sugiero que lea los documentos para ver qué sucede debajo del capó con print
función de print
y con sys.stdout
: http://docs.python.org/3/library/sys.html#sys.stdin
¡Espero que esto ayude!
Estoy trabajando en una secuencia de comandos de Python que usa el carácter de tijera (9986 - ✂) y estoy tratando de portar mi código a Mac, pero estoy teniendo este error.
El carácter de tijera aparece bien cuando se ejecuta desde IDLE (Python 3.2.5 - OS X 10.4.11 iBook G4 PPC) y el código funciona completamente bien en Ubuntu 13.10, pero cuando intento ejecutar esto en el terminal, obtengo este error / rastrear:
Traceback (most recent call last):
File "snippets-convert.py", line 352, in <module>
main()
File "snippets-convert.py", line 41, in main
menu()
File "snippets-convert.py", line 47, in menu
print ("|/t ",snipper.decode(),"PySnipt''d",snipper.decode(),"/t|")
UnicodeEncodeError: ''ascii'' codec can''t encode character ''/u2702'' in position 0: ordinal not in range(128)
y el código que me está dando el problema:
print ("|/t ",chr(9986),"PySnipt''d",chr(9986),"/t|")
¿No indica esto que el terminal no tiene la capacidad de mostrar ese carácter? Sé que este es un sistema antiguo, pero actualmente es el único sistema que tengo que usar. ¿Podría la edad del sistema operativo interferir con el programa?
He leído estas preguntas:
UnicodeEncodeError: el codec ''ascii'' no puede codificar el carácter u ''/ xef'' en la posición 0: ordinal no está dentro del rango (128) - Caracteres diferentes
"UnicodeEncodeError: el codec ''ascii'' no puede codificar el carácter" - Usando 2.6, así que no sé si se aplica
UnicodeEncodeError: el codec ''ascii'' no puede codificar caracteres? - Parece ser una solución plausible para mi problema,
.encode(''UTF-8'')
, no obtengo el error. Sin embargo, muestra un código de carácter, no el carácter que quiero, y.decode()
solo me da el mismo error. No estoy seguro de si estoy haciendo esto bien.UnicodeEncodeError: el codec ''ascii'' no puede codificar caracteres en la posición 0-6: ordinal no está en el rango (128) : no está seguro de si esto se aplica, está usando una GUI, está ingresando y todo en griego.
¿Qué está causando este error? ¿Es la edad del sistema / SO, la versión de Python o algún error de programación?
EDITAR : Este error surge más adelante con este problema duplicado (solo pensé que lo agregaría porque está dentro del mismo programa y es el mismo error):
Traceback (most recent call last):
File "snippets-convert.py", line 353, in <module>
main()
File "snippets-convert.py", line 41, in main
menu()
File "snippets-convert.py", line 75, in menu
main()
File "snippets-convert.py", line 41, in main
menu()
File "snippets-convert.py", line 62, in menu
search()
File "snippets-convert.py", line 229, in search
print_results(search_returned) # Print the results for the user
File "snippets-convert.py", line 287, in print_results
getPath(toRead) # Get the path for the snippet
File "snippets-convert.py", line 324, in getPath
snipXMLParse(path)
File "snippets-convert.py", line 344, in snipXMLParse
print (chr(164),child.text)
UnicodeEncodeError: ''ascii'' codec can''t encode character ''/xa4'' in position 0: ordinal not in range(128)
EDITAR:
Entré en la configuración de caracteres del terminal y, de hecho, es compatible con ese carácter (como se puede ver en esta captura de pantalla:
cuando lo inserto en el terminal, imprime esto: /342/234/202
y cuando -bash: ✂: command not found
Intro obtengo esto: -bash: ✂: command not found
EDITAR los comandos Ran como @JF Sebastian preguntó:
python3 test-io-encoding.py
:
PYTHONIOENCODING: None
locale(False): US-ASCII
device(stdout): US-ASCII
stdout.encoding: US-ASCII
device(stderr): US-ASCII
stderr.encoding: US-ASCII
device(stdin): US-ASCII
stdin.encoding: US-ASCII
locale(False): US-ASCII
locale(True): US-ASCII
python3 -S test-io-encoding.py
:
PYTHONIOENCODING: None
locale(False): US-ASCII
device(stdout): US-ASCII
stdout.encoding: US-ASCII
device(stderr): US-ASCII
stderr.encoding: US-ASCII
device(stdin): US-ASCII
stdin.encoding: US-ASCII
locale(False): US-ASCII
locale(True): US-ASCII
EDIT Probó la solución "hackerish" proporcionada por @PauloBu:
Como puede ver, esto causó una tijera (¡sí!), Pero ahora estoy recibiendo un nuevo error. Traceback / error:
+-=============================-+
✂Traceback (most recent call last):
File "snippets-convert.py", line 357, in <module>
main()
File "snippets-convert.py", line 44, in main
menu()
File "snippets-convert.py", line 52, in menu
print("|/t "+sys.stdout.buffer.write(chr(9986).encode(''UTF-8''))+" PySnipt''d "+ sys.stdout.buffer.write(chr(9986).encode(''UTF-8''))+" /t|")
TypeError: Can''t convert ''int'' object to str implicitly
EDITAR Resultados añadidos de la corrección de @ PauloBu:
+-=============================-+
|
✂ PySnipt''d
✂ |
+-=============================-+
EDITAR :
Y su solución para su corrección:
+-=============================-+
✂✂| PySnipt''d |
+-=============================-+
Mi configuración regional está establecida en de_AT.UTF-8 pero faltaban estas líneas en /etc/profile
:
export LANG=de_AT.UTF-8
export LANGUAGE=de_AT.UTF-8
export LC_ALL=de_AT.UTF-8
logout / login y su problema debe ser resuelto
Para verificar si todas las configuraciones regionales están configuradas correctamente, escriba la locale
en su terminal
La salida debe ser similar a esto:
LANG=de_AT.UTF-8
LANGUAGE=de_AT.UTF-8
LC_CTYPE="de_AT.UTF-8"
LC_NUMERIC="de_AT.UTF-8"
LC_TIME="de_AT.UTF-8"
LC_COLLATE="de_AT.UTF-8"
LC_MONETARY="de_AT.UTF-8"
LC_MESSAGES="de_AT.UTF-8"
LC_PAPER="de_AT.UTF-8"
LC_NAME="de_AT.UTF-8"
LC_ADDRESS="de_AT.UTF-8"
LC_TELEPHONE="de_AT.UTF-8"
LC_MEASUREMENT="de_AT.UTF-8"
LC_IDENTIFICATION="de_AT.UTF-8"
LC_ALL=de_AT.UTF-8
en la primera línea de su archivo .py necesita agregar esta cadena,:
# - - codificación: utf-8 - -
y también puedes probar esto:
print ("| / t", unichr (9986), "PySnipt''d", unichr (9986), "/ t |")
test_io_encoding.py
salida de test_io_encoding.py
sugiere que debería cambiar la configuración locale
, por ejemplo, establezca LANG=en_US.UTF-8
.
El primer error puede deberse a que está intentando decodificar una cadena que ya es Unicode. Python 2 intenta codificarlo utilizando una codificación de caracteres predeterminada ( ''ascii''
) antes de decodificarlo utilizando (posiblemente) una codificación de caracteres diferente. El error ocurre en el paso de encode
:
>>> u"/u2702".decode() # Python 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: ''ascii'' codec can''t encode character u''/u2702'' in position 0: ordinal not in range(128)
Parece que está ejecutando su script usando Python 2 en lugar de Python 3. Obtendría:
>>> "/u2702".decode() # Python 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: ''str'' object has no attribute ''decode''
error diferente de lo contrario.
Simplemente suelta la llamada .decode()
:
print("|/t {0} PySnipt''d {0} /t|".format(snipper))
El segundo problema se debe a la impresión de una cadena Unicode en una tubería:
$ python3 -c''print("/u2702")''
✂
$ python3 -c''print("/u2702")'' | cat
Traceback (most recent call last):
File "<string>", line 1, in <module>
UnicodeEncodeError: ''ascii'' codec can''t encode character ''/u2702'' in position 0: ordinal not in range(128)
Establecer adecuado para su propósito PYTHONIOENCODING
variable de entorno:
$ PYTHONIOENCODING=utf-8 python3 -c''print("/u2702")'' | cat
✂
el terminal solo muestra esto:
| b''/xe2/x9c/x82'' PySnipt''d b''/xe2/x9c/x82'' |
| b''/xe2/x9c/x82'' PySnipt''d b''/xe2/x9c/x82'' |
Si snipper
es un objeto de bytes
, deje las llamadas snipper.decode()
.
$ python3 -c"print(b''/xe2/x9c/x82''.decode())"
✂
$ python3 -c"print(b''/xe2/x9c/x82''.decode())" | cat
Traceback (most recent call last):
File "<string>", line 1, in <module>
UnicodeEncodeError: ''ascii'' codec can''t encode character ''/u2702'' in position 0: ordinal not in range(128)
La solución es la misma:
$ PYTHONIOENCODING=utf-8 python3 -c"print(b''/xe2/x9c/x82''.decode())" | cat
✂