Función de impresión () de Python 3 con caracteres farsi / árabes

Simplifiqué mi código para una mejor comprensión. Aquí está el problema:

caso 1:

# -*- coding: utf-8 -*- text = "چرا کار نمیکنی؟" # also using u"...." results the same print(text) 

salida:

 UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to  

caso 2:

 text = "چرا کار نمیکنی؟".encode("utf-8") print(text) 

no hay salida

caso 3:

 import sys text = "چرا کار نمیکنی؟".encode("utf-8") sys.stdout.buffer.write(text) 

salida:

 چرا کار نمیکنی؟ 

Sé que el caso 3 funciona de alguna manera, pero quiero usar otras funciones como imprimir (), escribir (str ()), …

También leí la documentación de python 3 con respecto a Unicode aquí .

y también leer docenas de preguntas y respuestas en stackoverflow.

y aquí hay un largo artículo que explica el problema y la respuesta para Python 2.X

La pregunta simple es:

¿Cómo imprimir caracteres no ASCII como farsi o árabe usando la función print () de python?

actualización 1: como se sugiere de muchos chicos, el problema está relacionado con el terminal que probé en el caso:

caso 4:

 text = "چرا کار نمیکنی؟" .encode("utf-8")# also using u"...." results the same print(text) 

terminal :

 python persian_encoding.py > test.txt 

test.txt:

 b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' 

actualización muy importante:

Después de un rato jugando con este problema, finalmente encontré otra solución para hacer que cmd.exe haga el trabajo (sin necesidad de software de terceros como ConEmu o …):

Una pequeña explicación primero:

Nuestro principal problema no concierne a Python. es un problema con el conjunto de caracteres de la línea de comandos en Windows (para una explicación completa, consulte la Respuesta de Arman), por lo tanto … si cambia el conjunto de caracteres de la línea de comandos de Windows a UTF-8 en lugar del ascii predeterminado, entonces la línea de comandos podrá para interactuar con los caracteres UTF-8 (como farsi o árabe), esta solución no garantiza una buena representación de los caracteres (ya que se imprimirán como pequeños cuadrados), pero es una buena solución si desea tener la E / S de archivos en Python con caracteres UTF-8.

Pasos:

antes de iniciar python desde la línea de comandos, escriba:

 chcp 65001 

ahora ejecuta tu código python como siempre.

 python testcode.py 

resultado en el caso 1:

 ?????? ??? ?????? 

Se ejecuta sin errores.

captura de pantalla:

introduzca la descripción de la imagen aquí

para obtener más información sobre cómo configurar 65001 como el conjunto de caracteres predeterminado, verifique esto .

Tu código es correcto, ya que funciona en mi computadora con Python 2 y 3 (estoy en OS X):

 ~$ python -c 'print "تست"' تست ~$ python3 -c 'print("تست")' تست 

El problema está en su terminal que no puede generar caracteres Unicode. Puede verificarlo redirigiendo su salida a un archivo como python3 my_file.py > test.txt y abrir el archivo con un editor.

Si está en Windows, puede utilizar un terminal como Console2 o ConEmu que se ejecute Unicode mejor que el indicador de Windows.

También puede encontrar errores con estos terminales debido a las codificaciones / codificaciones incorrectas de Windows. Hay un pequeño paquete de Python que los corrige (los configura correctamente):

1- Instalar este pip install win-unicode-console

2- Pon esto en la parte superior de tu archivo python:

 try: # Fix UTF8 output issues on Windows console. # Does nothing if package is not installed from win_unicode_console import enable enable() except ImportError: pass 

Si tiene errores al redirigir a un archivo, puede corregirlo configurando la encoding io:

En la línea de comando de Windows:

 SET PYTHONIOENCODING=utf-8 

En el terminal Linux / OS X:

 export PYTHONIOENCODING=utf-8 

Algunos puntos

  • No hay necesidad de usar la syntax de u"aaa" en Python 3. Las cadenas literales son unicode de forma predeterminada.
  • La encoding predeterminada de los archivos es UTF8 en Python 3, por lo que el comentario de la statement de encoding (por ejemplo, # -*- coding: utf-8 -*- ) no es necesario.

La salida dependerá básicamente de qué plataforma y terminal ejecute su código. Examinemos el siguiente fragmento de código para diferentes terminales de Windows que se ejecutan con 2.x o 3.x:

 # -*- coding: utf-8 -*- import sys def case1(text): print(text) def case2(text): print(text.encode("utf-8")) def case3(text): sys.stdout.buffer.write(text.encode("utf-8")) if __name__ == "__main__": text = "چرا کار نمیکنی؟" for case in [case1, case2, case3]: try: print("Running {0}".format(case.__name__)) case(text) except Exception as e: print(e) print('-'*80) 

Resultados

Python 2.x

 Sublime Text 3 3122 Running case1 'charmap' codec can't encode characters in position 0-2: character maps to  -------------------------------------------------------------------------------- Running case2 b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' -------------------------------------------------------------------------------- Running case3 چرا کار نمیکنی؟-------------------------------------------------------------------------------- 

ConEmu v151205

  Running case1 ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ -------------------------------------------------------------------------------- Running case2 'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128) -------------------------------------------------------------------------------- Running case3 'file' object has no attribute 'buffer' -------------------------------------------------------------------------------- 

Símbolo del sistema de Windows

  Running case1 ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ -------------------------------------------------------------------------------- Running case2 'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128) -------------------------------------------------------------------------------- Running case3 'file' object has no attribute 'buffer' -------------------------------------------------------------------------------- 

Python 3.x

 Sublime Text 3 3122 Running case1 'charmap' codec can't encode characters in position 0-2: character maps to  -------------------------------------------------------------------------------- Running case2 b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' -------------------------------------------------------------------------------- Running case3 چرا کار نمیکنی؟-------------------------------------------------------------------------------- 

ConEmu v151205

  Running case1 'charmap' codec can't encode characters in position 0-2: character maps to  -------------------------------------------------------------------------------- Running case2 b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' -------------------------------------------------------------------------------- Running case3 ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ-------------------------------------------------------------------------------- 

Símbolo del sistema de Windows

  Running case1 'charmap' codec can't encode characters in position 0-2: character maps to  -------------------------------------------------------------------------------- Running case2 b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda \xa9\xd9\x86\xdb\x8c\xd8\x9f' -------------------------------------------------------------------------------- Running case3 ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ---------------------------------------------------- ---------------------------- 

Como puede ver, el uso de sublime text3 terminal (case3) funcionó bien. Los otros terminales no soportaban persa. El punto principal aquí es, depende de qué terminal y plataforma está utilizando.

Solución (específica de ConEmu)

Los terminales modernos como ConEmu le permiten trabajar con encoding UTF8 como se explica aquí , así que, probemos:

 chcp 65001 & cmd 

Y luego ejecutando de nuevo el script contra 2.x y 3.x:

Python2.x

 Running case1   را کار نمیکنی؟[Errno 0] Error -------------------------------------------------------------------------------- Running case2 'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128) -------------------------------------------------------------------------------- Running case3 'file' object has no attribute 'buffer' -------------------------------------------------------------------------------- 

Python3.x

 Running case1 چرا کار نمیکنی؟ -------------------------------------------------------------------------------- Running case2 b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' -------------------------------------------------------------------------------- Running case3 چرا کار نمیکنی؟-------------------------------------------------------------------------------- 

Como puede ver, ahora la salida fue exitosa con python3 case1 (imprimir). Entonces … moraleja de una fábula … aprenda más sobre sus herramientas y cómo configurarlas adecuadamente para sus casos de uso 😉

No puedo reproducir el problema. Aquí está mi guión p.py :

 text = "چرا کار نمیکنی؟" print(text) 

Y el resultado de python3 p.py :

 چرا کار نمیکنی؟ 

¿Estás seguro de que estás usando python 3? Con python2 p.py :

 SyntaxError: Non-ASCII character '\xda' in file p.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details 

Y si haces el text.encode("utf-8") -part, se mostrará como b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' (en mi máquina).

EDITAR Perdón por la edición, pero no puedo comentar (porque no tengo suficiente reputación)

Incluso en Python 2.7, la print(text) funciona. Echa un vistazo a este enlace aquí, que acabo de generar.