Python 3 的print()函数使用 波斯语/阿拉伯语 字符。
Python 3 的print()函数使用 波斯语/阿拉伯语 字符。
这个问题已经有答案了:
我简化了我的代码以便更好地理解。
这是问题:
情况1:
# -*- coding: utf-8 -*- text = "چرا کار نمیکنی؟" # also using u"...." results the same print(text)
输出:
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to
情况2:
text = "چرا کار نمیکنی؟".encode("utf-8") print(text)
没有输出。
情况 3:
import sys text = "چرا کار نمیکنی؟".encode("utf-8") sys.stdout.buffer.write(text)
输出:
چرا کار نمیکنی؟
我知道情况3在某种程度上是可以工作的,但我想使用其他函数,如print()、write(str())等。
我还阅读了关于Unicode的Python 3文档这里。
并读了许多个关于此问题的Q&A。
这里有一篇长文解释了Python 2.X的问题和答案。
简单的问题是:
如何使用python print()函数打印非ASCII字符,如波斯语或阿拉伯语?
更新1:
由于许多人建议这个问题与终端有关,所以我测试了情况:
情况4:
text = "چرا کار نمیکنی؟" .encode("utf-8")# also using u"...." results the same print(text)
终端:
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'
非常重要的更新:
经过一段时间的玩弄,最终我发现了另一种解决办法,让cmd.exe完成此工作(无需第三方软件如ConEmu或...):
首先解释一下:
我们的主要问题不涉及Python,而是Windows命令提示符字符集的问题(详细说明请参见Arman的答案)
所以......如果将Windows命令提示符的字符集从默认的ASCII改为UTF-8,则命令提示符将能够与UTF-8字符(如波斯语或阿拉伯语)进行交互。这种解决方案不能保证字符的良好表示(因为它们会被打印成小方块),但如果您想使用带有UTF-8字符的Python进行文件输入/输出,则是一个好的解决方案。
步骤:
在从命令行启动Python之前,输入:
chcp 65001
现在,像往常一样运行您的Python代码。
python testcode.py
第一种情况的结果:
?????? ??? ??????
运行没有错误。
屏幕截图:
有关如何将65001设置为默认字符集的更多信息,请参见此处。
输出将根据你所运行代码的平台和终端而定。让我们检查下面的代码片段在不同的窗口终端上运行的情况,无论是在2.x还是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)
结果
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' --------------------------------------------------------------------------------
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 ┌åÏ▒Ϻ ┌ϺÏ▒ ┘å┘à█î┌┘å█îσ--------------------------------------------------------------------------------
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 ┌åÏ▒Ϻ ┌ϺÏ▒ ┘å┘à█î┌┘å█îσ---------------------------------------------------- ----------------------------
你可以看到,只使用sublime text3终端(case3)工作得很好。其他终端不支持波斯语。这里的主要问题是,它取决于你使用的终端和平台。
解决方案(ConEmu特定)
像ConEmu这样的现代终端允许你使用UTF8编码,如这里所解释的,所以让我们尝试一下:
chcp 65001 & cmd
然后再次对2.x和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 چرا کار نمیکنی؟--------------------------------------------------------------------------------
你可以看到,现在Python3 case1(print)的输出成功了。所以……寓言的寓意是学习更多关于你的工具以及如何为你的用例正确地配置它们;-)
你的代码是正确的,因为它在我的电脑上同时使用Python 2和3都能正常工作(我的操作系统是OS X):
~$ python -c 'print "تست"' تست ~$ python3 -c 'print("تست")' تست
问题在于你的终端无法输出Unicode字符。你可以通过将输出重定向到文件,例如python3 my_file.py > test.txt
,然后使用编辑器打开文件进行验证。
如果你在Windows系统上,你可以使用像Console2或ConEmu这样的终端,它们能够比Windows命令提示符更好地呈现Unicode。
你可能仍会在这些终端中遇到错误,因为Windows的编码不正确。有一个小的Python包可以修复它们(设置它们的编码):
1- 安装这个pip install win-unicode-console
2- 将这个放在你的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
如果你在将输出重定向到文件时遇到错误,可以通过设置IO编码来修复它:
在Windows命令行中:
SET PYTHONIOENCODING=utf-8
在Linux/OS X 终端中:
export PYTHONIOENCODING=utf-8
一些要点
- 在Python 3中不需要使用
u"aaa"
来表示unicode字符串,因为字符串字面量默认就是unicode。 - 在Python 3中,默认文件编码为UTF8,因此不需要编码声明注释(例如
# -*- coding: utf-8 -*-
)。