Python 3 print()函数,包含波斯语/阿拉伯字符

时间:2016-09-16 09:48:48

标签: python python-3.x unicode utf-8

我简化了我的代码以便更好地理解。 这是问题:

案例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 <undefined>

案例2:

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

没有输出。

case 3:

import sys

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

输出:

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

我知道案例3以某种方式工作,但我想使用其他函数,如print(),write(str()),....

我还阅读了关于Unicode here的python 3的文档。

并且还在stackoverflow中读取了数十个Q&amp; A.

here是一篇很长的文章,解释了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命令提示符的字符集更改为UTF-8而不是默认的ascii,那么命令提示符将能够与UTF-8字符(如波斯语或阿拉伯语)进行交互,此解决方案不能保证良好的表示字符(因为它们将像小方块一样打印出来),但如果你想在python中使用UTF-8字符进行文件I / O,这是一个很好的解决方案。

步骤:

在从命令行启动python之前,输入:

chcp 65001

现在一如既往地运行你的python代码。

python testcode.py

结果案例1:

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

它运行没有错误。

截图:

enter image description here

有关如何将65001设置为默认字符集check this的更多信息。

4 个答案:

答案 0 :(得分:6)

您的代码是正确的,因为它在我的计算机上同时适用于Python 2和3(我在OS X上):

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

问题在于您的终端无法输出unicode字符。您可以通过将输出重定向到python3 my_file.py > test.txt等文件来验证它,并使用编辑器打开文件。

如果你在Windows上,你可以使用像Console2ConEmu这样的终端,它比Windows提示更好地呈现unicode。

由于Windows的代码页/编码错误,您可能也会遇到这些终端的错误。有一个小python包修复它们(正确设置它们):

1-安装this 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

如果在重定向到文件时遇到错误,可以通过设置编码来修复它:

在Windows命令行上:

SET PYTHONIOENCODING=utf-8

在Linux / OS X终端上:

export PYTHONIOENCODING=utf-8

一些要点

  • 在python 3中不需要使用u"aaa"语法。默认情况下,字符串文字是unicode。
  • 文件的默认编码是python 3中的UTF8,因此不需要编码声明注释(例如# -*- coding: utf-8 -*-)。

答案 1 :(得分:4)

输出主要取决于您运行代码的平台和终端。让我们检查下面使用2.x或3.x运行的不同Windows终端的代码段:

# -*- 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 <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'
    --------------------------------------------------------------------------------

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
    ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ--------------------------------------------------------------------------------

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
    ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ----------------------------------------------------
    ----------------------------

正如你所看到的那样,使用sublime text3终端(case3)工作正常。其他终端不支持波斯语。这里的要点是,它取决于哪个终端&amp;你正在使用的平台。

解决方案(特定于ConEmu)

像ConEmu这样的现代终端允许你使用UTF8-Encoding作为explained here,所以,让我们试试:

chcp 65001 & cmd

然后再次针对2.x&amp;运行脚本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)输出成功了。所以...寓言的道德......了解更多关于你的工具以及如何正确配置它们的用例; - )

答案 2 :(得分:1)

我无法重现这个问题。这是我的脚本p.py

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

python3 p.py的结果:

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

你确定你正在使用python 3吗?使用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

答案 3 :(得分:0)

如果您执行php[41369] general protection ip:5c0cc3 sp:7fff281f0d98 error:0 in php[400000+33c000] php[41399] general protection ip:5c0cc3 sp:7fffad17fd68 error:0 in php[400000+33c000] php[41408] general protection ip:5c0cc3 sp:7fff84481ce8 error:0 in php[400000+33c000] php[41412] general protection ip:5c0cc3 sp:7fff56af32f8 error:0 in php[400000+33c000] php[41417] general protection ip:5c0cc3 sp:7fff1e4d1ca8 error:0 in php[400000+33c000] php[41426] general protection ip:5c0cc3 sp:7fff87a67108 error:0 in php[400000+33c000] php[41431] general protection ip:5c0cc3 sp:7fffb16bacc8 error:0 in php[400000+33c000] php[41437] general protection ip:5c0cc3 sp:7fffbc41d5c8 error:0 in php[400000+33c000] - 部分,它将显示为text.encode("utf-8")(在我的机器上)。

修改 抱歉编辑,但我无法发表评论(因为声誉不够)

即使在python 2.7上,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'也能正常工作。查看我刚刚生成的this link