Python,Unicode和Windows控制台
当我尝试在Windows控制台中打印Unicodestring时,出现UnicodeEncodeError: 'charmap' codec can't encode character ....
错误。 我认为这是因为Windows控制台不接受只有Unicode的字符。 什么是最好的方法呢? 有什么办法可以让Python自动打印?
而不是在这种情况下失败?
编辑:我正在使用Python 2.5。
注意: @ LasseV.Karlsen答案与复选标记是有点过时(从2008年)。 请小心使用下面的解决scheme/答案/build议!
从今天(2016年1月6日)起, @JFSebastian的答案更具相关性。
注意:这个答案有些过时(从2008年)。 请小心使用下面的解决scheme!
这里是一个详细的问题和解决scheme的页面(search文本环绕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 Б Б
这个页面上还有更多的信息,非常值得一读。
更新: Python 3.6实现PEP 528:将Windows控制台编码更改为UTF-8 : Windows上的默认控制台现在将接受所有Unicode字符。 在内部,它使用与下面提到的win-unicode-console
包相同的Unicode API。 print(unicode_string)
现在应该只是工作。
我得到一个
UnicodeEncodeError: 'charmap' codec can't encode character...
错误。
该错误意味着您尝试打印的Unicode字符无法使用当前( chcp
)控制台字符编码表示。 代码页通常是8位编码,如cp437
,可以表示cp437
Unicode字符中的cp437
字符:
>>> u“\ N {EURO SIGN}”。encode('cp437') 回溯(最近一次通话最后): ... UnicodeEncodeError:'charmap'编解码器不能在位置0编码字符'\ u20ac': 字符映射到
我认为这是因为Windows控制台不接受只有Unicode的字符。 什么是最好的方法呢?
Windows控制台不接受Unicode字符, 如果configuration了相应的字体 ,它甚至可以显示它们(仅限于 BMP)。 WriteConsoleW()
API应按照@Daira Hopwood的回答build议使用。 它可以被透明地调用,即如果你使用win-unicode-console
包 ,你不需要也不应该修改你的脚本:
T:\> py -mpip install win-unicode-console T:\> py -mrun your_script.py
看看Python 3.4,Unicode,不同的语言和Windows有什么关系?
有什么办法可以让Python自动打印
?
而不是在这种情况下失败?
如果足以将所有不可编码的字符replace为?
在你的情况,那么你可以设置PYTHONIOENCODING
envvar :
T:\> set PYTHONIOENCODING=:replace T:\> python3 -c "print(u'[\N{EURO SIGN}]')" [?]
在Python 3.6+中,除非PYTHONLEGACYWINDOWSIOENCODING
envvar设置为非空string,否则对于交互式控制台缓冲区,由PYTHONIOENCODING
envvar指定的编码将被忽略。
尽pipe其他合理的答案,build议将代码页更改为65001,这是行不通的 。 (另外,使用sys.setdefaultencoding
更改默认编码不是一个好主意 。)
看到这个问题的细节和代码,确实工作。
如果你不想获得可靠的坏字符表示,你可以使用类似的东西(使用python> = 2.6,包括3.x):
from __future__ import print_function import sys def safeprint(s): try: print(s) except UnicodeEncodeError: if sys.version_info >= (3,): print(s.encode('utf8').decode(sys.stdout.encoding)) else: print(s.encode('utf8')) safeprint(u"\N{EM DASH}")
string中的错误字符将被转换为可由Windows控制台打印的表示forms。
下面的代码将使Python输出到UTF-8,即使在Windows上。
控制台将在Windows 7上很好地显示字符,但是在Windows XP上它不能很好地显示它们,但至less它能够正常工作,而且最重要的是,在所有平台上,脚本都将具有一致的输出。 您将能够将输出redirect到一个文件。
下面的代码在Windows上用Python 2.6进行了testing。
#!/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"
就像GiampaoloRodolà的回答一样,但更加肮脏:我确实打算花很长时间(很快)来理解整个编码主题,以及它们如何应用于Windoze控制台,
就目前来说,我只是想要sthg,这意味着我的程序不会被破坏,而且我也明白了…也不涉及导入太多奇特的模块(特别是我使用Jython,所以有一半是Python模块事实上不可用)。
def pr(s): try: print(s) except UnicodeEncodeError: for c in s: try: print( c, end='') except UnicodeEncodeError: print( '?', end='')
NB“PR”比“打印”短(types比“safeprint”短得多)…!
Python 3.6的Windows7:有几种方法可以启动一个Python可以使用Python控制台(其上有一个Python标志)或Windows控制台(它写在它的cmd.exe)。
我无法在Windows控制台中打印utf8字符。 打印utf-8字符丢给我这个错误:
OSError: [winError 87] The paraneter is incorrect Exception ignored in: (_io-TextIOwrapper name='(stdout)' mode='w' ' encoding='utf8') OSError: [WinError 87] The parameter is incorrect
在尝试和不明白上面的答案后,我发现这只是一个设置问题。 右键单击cmd控制台窗口的顶部,在选项卡font
select了lucida控制台。
对于Python 2,请尝试:
打印unicode(string,'unicode-escape')
对于Python 3,请尝试:
import操作系统
string='002可能应该会'
os.system('echo'+ string)
或者试试win-unicode-console:
pip安装win-unicode-console
py -mrun your_script.py
你的问题的原因是不是 Win的控制台不愿意接受Unicode(因为它是这样做的,因为我猜Win2k的默认情况下)。 这是默认的系统编码。 试试这段代码,看看它给了你什么:
import sys sys.getdefaultencoding()
如果它说ascii,这是你的原因;-)你必须创build一个名为sitecustomize.py文件,并把它放在pythonpath下(我把它放在/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书中find
JF Sebastian的回答有点类似,但更直接。
如果打印到控制台/terminal时遇到此问题,请执行以下操作:
>set PYTHONIOENCODING=UTF-8
James Sulak问,
有什么办法可以让Python自动打印? 而不是在这种情况下失败?
其他解决schemebuild议我们尝试修改Windows环境或replacePython的print()
函数。 下面的答案更接近满足了苏拉克的要求。
在Windows 7下,可以使Python 3.5打印Unicode而不抛出UnicodeEncodeError
,如下所示:
取代: print(text)
substitute: print(str(text).encode('utf-8'))
Python不会抛出exception,而是将不可打印的Unicode字符显示为\ xNNhex代码,例如:
Halmalo n×x80 x99 xc3 xa9tait plus qu \ xe2 \ x80 \ x99un点noir
代替
Halmalon'était加qu'un点黑色
当然,后者更可取,但前者对于诊断信息是完全准确的。 因为它将Unicode显示为文字字节值,所以前者也可以帮助诊断编码/解码问题。
注意:上面的str()
调用是需要的,否则encode()
会导致Python拒绝Unicode字符作为数字元组。