Función print() de Python 3 con caracteres en farsi/árabe
python-3.x unicode (4)
La salida dependerá básicamente de qué plataforma y terminal ejecute su código. Examinemos el siguiente fragmento para diferentes terminales de Windows que se ejecutan con 2.xo 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 <undefined>
--------------------------------------------------------------------------------
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 <undefined>
--------------------------------------------------------------------------------
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 <undefined>
--------------------------------------------------------------------------------
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 <unde
fined>
--------------------------------------------------------------------------------
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. Las otras terminales no admitían persa. El punto principal aquí es que depende de qué terminal y plataforma esté utilizando.
Solución (específica de ConEmu)
Los terminales modernos como ConEmu le permiten trabajar con codificación UTF8 como se explica aquí , así que intentemos:
chcp 65001 & cmd
Y luego ejecutando nuevamente el script contra 2.xy 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 (print). Entonces ... moraleja de una fábula ... aprenda más sobre sus herramientas y cómo configurarlas adecuadamente para sus casos de uso ;-)
Esta pregunta ya tiene una respuesta aquí:
- Python, Unicode y la consola de Windows 13 respuestas
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 <undefined>
caso 2:
text = "چرا کار نمیکنی؟".encode("utf-8")
print(text)
No hay salida.
case 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 print (), write (str ()), ....
También leí la documentación de Python 3 con respecto a Unicode here .
y también lee docenas de preguntas y respuestas en stackoverflow.
y here hay un artículo largo que explica el problema y la respuesta para python 2.X
La simple pregunta es:
¿Cómo imprimir caracteres no ASCII como farsi o árabe usando la función python print ()?
Actualización 1: como muchos chicos sugieren que el problema está relacionado con el terminal, probé 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 tiempo 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 del símbolo del sistema en Windows (para obtener una explicación completa, consulte la respuesta de Arman) así que ... si cambia el conjunto de caracteres del símbolo del sistema de Windows a UTF-8 en lugar de ASCII predeterminado, el símbolo del sistema podrá Para interactuar con 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 cuadrados pequeños), pero es una buena solución si desea tener E / S de archivo en Python con caracteres UTF-8.
Pasos:
antes de iniciar python desde la línea de comando, 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:
Para obtener más información sobre cómo configurar 65001 como el juego de caracteres predeterminado, consulte this .
No puedo reproducir el problema.
Aquí está mi script
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
Su 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 es con su terminal que no puede generar caracteres unicode.
Puede verificarlo redirigiendo su salida a un archivo como
python3 my_file.py > test.txt
y abra el archivo con un editor.
Si está en Windows, podría usar un terminal como Console2 o ConEmu que represente unicode mejor que el indicador de Windows.
También puede encontrar errores con estos terminales debido a las páginas de códigos / codificaciones incorrectas de Windows. Hay un pequeño paquete de Python que los repara (los establece correctamente):
1- Instala
this
pip install win-unicode-console
2- Pon esto en la parte superior de tu archivo de 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 solucionarlo configurando la codificación 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 sintaxis
u"aaa"
en python 3. Los literales de cadenas son unicode por defecto. -
La codificación predeterminada de los archivos es UTF8 en python 3, por lo que no se necesita el comentario de la declaración de codificación (por ejemplo,
# -*- coding: utf-8 -*-
).
Y si hace la parte
text.encode("utf-8")
, 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 hay suficiente reputación)
Incluso en Python 2.7, la
print(text)
funciona.
Mira
este enlace
aquí, que acabo de generar.