xf1 utf8 tildes reemplazar colocar coding codificacion cambiar acentos python shell encoding utf-8 ascii

utf8 - utf-8 python



¿Cómo imprimir texto codificado en UTF-8 a la consola en Python<3? (3)

Estoy ejecutando un sistema Linux reciente donde todas mis configuraciones regionales son UTF-8:

LANG=de_DE.UTF-8 LANGUAGE= LC_CTYPE="de_DE.UTF-8" LC_NUMERIC="de_DE.UTF-8" LC_TIME="de_DE.UTF-8" ... LC_IDENTIFICATION="de_DE.UTF-8" LC_ALL=

Ahora quiero escribir contenido codificado en UTF-8 en la consola.

En este momento Python usa UTF-8 para la codificación FS, pero se adhiere a ASCII para la codificación predeterminada :-(

>>> import sys >>> sys.getdefaultencoding() ''ascii'' >>> sys.getfilesystemencoding() ''UTF-8''

Pensé que la mejor (limpia) forma de hacerlo era establecer la variable de entorno PYTHONIOENCODING . Pero parece que Python lo ignora. Al menos en mi sistema sigo recibiendo ascii como codificación predeterminada, incluso después de configurar el envvar .

# tried this in ~/.bashrc and ~/.profile (also sourced them) # and on the commandline before running python export PYTHONIOENCODING=UTF-8

Si hago lo siguiente al comienzo de un script, funciona bien:

>>> import sys >>> reload(sys) # to enable `setdefaultencoding` again <module ''sys'' (built-in)> >>> sys.setdefaultencoding("UTF-8") >>> sys.getdefaultencoding() ''UTF-8''

Pero ese enfoque parece sucio . Entonces, ¿cuál es una buena manera de lograr esto?

Solución

En lugar de cambiar la codificación predeterminada, que no es una buena idea (ver la respuesta de mesilliac), simplemente sys.stdout con un StreamWriter como este:

sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)

Vea esta idea para una pequeña función de utilidad, que lo maneja.


¿Cómo imprimir texto codificado en UTF-8 a la consola en Python <3?

print u"some unicode text /N{EURO SIGN}" print b"some utf-8 encoded bytestring /xe2/x82/xac".decode(''utf-8'')

es decir, si tiene una cadena Unicode, imprímala directamente. Si tiene una cadena de bytes, primero conviértalo en Unicode.

La configuración regional ( LANG , LC_CTYPE ) indica una configuración regional utf-8 y, por lo tanto (en teoría) podría imprimir directamente una cadena de bytes utf-8 y debería mostrarse correctamente en su terminal (si la configuración del terminal es coherente con la configuración regional y debería ser) pero debes evitarlo: no codificar la codificación de caracteres de tu entorno dentro de tu script ; imprime Unicode directamente en su lugar .

Hay muchas suposiciones equivocadas en su pregunta.

No necesita configurar PYTHONIOENCODING con su configuración regional para imprimir Unicode en la terminal. La configuración regional de utf-8 admite todos los caracteres Unicode, es decir, funciona tal cual.

No necesita la solución sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout) . Se puede romper si algún código (que no controla) necesita imprimir bytes y / o puede romperse mientras se imprime Unicode en la consola de Windows (página de códigos incorrecta, no puede imprimir caracteres indecodificables) . Las configuraciones locales correctas y / o el PYTHONIOENCODING PYTHONIOENCODING son suficientes. Además, si necesita reemplazar sys.stdout , utilice io.TextIOWrapper() lugar del módulo de codecs , como lo hace el paquete win-unicode-console .

sys.getdefaultencoding() no está relacionado con la configuración regional y con PYTHONIOENCODING . Su suposición de que establecer PYTHONIOENCODING debería cambiar sys.getdefaultencoding() es incorrecta. Debería verificar sys.stdout.encoding en sys.stdout.encoding lugar.

sys.getdefaultencoding() no se usa cuando imprime en la consola. Se puede usar como respaldo en Python 2 si stdout se redirige a un archivo / conducto a menos que se establezca PYTHOHIOENCODING :

$ python2 -c''import sys; print(sys.stdout.encoding)'' UTF-8 $ python2 -c''import sys; print(sys.stdout.encoding)'' | cat None $ PYTHONIOENCODING=utf8 python2 -c''import sys; print(sys.stdout.encoding)'' | cat utf8

No llame a sys.setdefaultencoding("UTF-8") ; puede dañar sus datos de forma silenciosa y / o romper módulos de terceros que no lo esperan. Recuerde que sys.getdefaultencoding() se usa para convertir cadenas de bytes ( str ) a / desde unicode en Python 2 implícitamente , por ejemplo, "a" + u"b" . Ver también, la cita en la respuesta de @mesilliac .


Así es como lo hago:

#!/usr/bin/python2.7 -S import sys sys.setdefaultencoding("utf-8") import site

Tenga en cuenta el -S en el bangline. Eso le dice a Python que no importe automáticamente el módulo del site . El módulo de site es el que establece la codificación predeterminada y elimina el método para que no se pueda volver a establecer. Pero honrará lo que ya está establecido.


Parece que lograr esto no es recomendable.

Fedora sugirió usar la configuración regional del sistema como predeterminada , pero aparentemente esto rompe otras cosas.

Aquí hay una cita de la discusión de la lista de correo :

The only supported default encodings in Python are: Python 2.x: ASCII Python 3.x: UTF-8 If you change these, you are on your own and strange things will start to happen. The default encoding does not only affect the translation between Python and the outside world, but also all internal conversions between 8-bit strings and Unicode. Hacks like what''s happening in the pango module (setting the default encoding to ''utf-8'' by reloading the site module in order to get the sys.setdefaultencoding() API back) are just downright wrong and will cause serious problems since Unicode objects cache their default encoded representation. Please don''t enable the use of a locale based default encoding. If all you want to achieve is getting the encodings of stdout and stdin correctly setup for pipes, you should instead change the .encoding attribute of those (only). -- Marc-Andre Lemburg eGenix.com