Python,Unicode和Windows控制台
当我尝试在Windows控制台中打印Unicode字符串时,出现UnicodeEncodeError:'charmap'编解码器无法编码字符....错误。我认为这是因为Windows控制台不接受仅Unicode字符。最好的办法是什么?有什么方法可以使Python自动打印
?`而不是在这种情况下失败?
编辑:我正在使用Python 2.5.
注意:带有对勾标记的@ LasseV.Karlsen答案有些过时(自2008年起)。请谨慎使用以下解决方案/答案/建议!!
截至今天(2016年1月6日),@ JFSebastian的答案更加相关。
解决方案
回答
注意:这个答案有点过时了(从2008年开始)。请谨慎使用以下解决方案!!
这是详细描述问题和解决方案的页面(在页面中将文本sys.stdout包装到实例中搜索):
PrintFails Python Wiki
这是该页面的代码摘录:
$ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \ sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \ line = u"\u0411\n"; print type(line), len(line); \ sys.stdout.write(line); print line' UTF-8 <type 'unicode'> 2 Б Б $ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \ sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \ line = u"\u0411\n"; print type(line), len(line); \ sys.stdout.write(line); print line' | cat None <type 'unicode'> 2 Б Б
该页面上有更多信息,非常值得一读。
回答
我们出现问题的原因不是Win控制台不愿意接受Unicode(因为这样做是因为我猜默认是Win2k)。它是默认的系统编码。试试下面的代码,看看它能为我们带来什么:
import sys sys.getdefaultencoding()
如果显示ascii,那是原因;-)
我们必须创建一个名为sitecustomize.py的文件并将其放在python路径下(我将其放在/usr/lib/python2.5/site-packages下,但在Win上有所不同,它是c:\ python \ lib \ site -packages或者其他内容),其中包含以下内容:
import sys sys.setdefaultencoding('utf-8')
也许我们可能还需要在文件中指定编码:
# -*- coding: UTF-8 -*- import sys,time
编辑:更多信息可在优秀的《深入Python》一书中找到
回答
以下代码即使在Windows上也可以将Python输出作为UTF-8控制台输出。
控制台将在Windows 7上很好地显示字符,但在Windows XP上将不能很好地显示字符,但是至少它可以正常工作,最重要的是,我们将在所有平台上从脚本中获得一致的输出。我们将能够将输出重定向到文件。
下面的代码已在Windows上使用Python 2.6进行了测试。
#!/usr/bin/python # -*- coding: UTF-8 -*- import codecs, sys reload(sys) sys.setdefaultencoding('utf-8') print sys.getdefaultencoding() if sys.platform == 'win32': try: import win32console except: print "Python Win32 Extensions module is required.\n You can download it from https://sourceforge.net/projects/pywin32/ (x86 and x64 builds are available)\n" exit(-1) # win32console implementation of SetConsoleCP does not return a value # CP_UTF8 = 65001 win32console.SetConsoleCP(65001) if (win32console.GetConsoleCP() != 65001): raise Exception ("Cannot set console codepage to 65001 (UTF-8)") win32console.SetConsoleOutputCP(65001) if (win32console.GetConsoleOutputCP() != 65001): raise Exception ("Cannot set console output codepage to 65001 (UTF-8)") #import sys, codecs sys.stdout = codecs.getwriter('utf8')(sys.stdout) sys.stderr = codecs.getwriter('utf8')(sys.stderr) print "This is an Е乂αmp?? testing Unicode support using Arabic, Latin, Cyrillic, Greek, Hebrew and CJK code points.\n"