当我尝试在Windows控制台中打印Unicode字符串时,出现UnicodeEncodeError: 'charmap' codec can't encode character ....
错误.我认为这是因为Windows控制台不接受仅Unicode字符.最好的方法是什么??
在这种情况下,有什么方法可以让Python自动打印而不是失败?
编辑: 我正在使用Python 2.5.
注意: @ LasseV.Karlsen回答带有复选标记有点过时(从2008年开始).请谨慎使用下面的解决方案/答案/建议!!
截至今天(2016年1月6日),@ JFSebastian答案更为相关.
jfs*_*jfs 70
更新: 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字符无法使用current(chcp
)控制台字符编码表示.代码页通常是8位编码,例如,cp437
它只能表示来自〜1M Unicode字符的~0x100个字符:
>>> u"\N{EURO SIGN}".encode('cp437') Traceback (most recent call last): ... UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position 0: character maps to
我认为这是因为Windows控制台不接受仅Unicode字符.最好的方法是什么?
Windows控制台确实接受Unicode字符,如果配置了相应的字体,它甚至可以显示它们(仅限BMP).WriteConsoleW()
应该按照@Daira Hopwood的回答中的建议使用API .它可以透明地调用,即如果使用win-unicode-console
包,则不需要也不应该修改脚本:
T:\> py -mpip install win-unicode-console
T:\> py -mrun your_script.py
Run Code Online (Sandbox Code Playgroud)
请参阅Python 3.4,Unicode,不同语言和Windows有什么用?
?
在这种情况下,有什么方法可以让Python自动打印而不是失败?
如果足以?
在您的情况下替换所有不可编码的字符,那么您可以设置PYTHONIOENCODING
envvar:
T:\> set PYTHONIOENCODING=:replace
T:\> python3 -c "print(u'[\N{EURO SIGN}]')"
[?]
Run Code Online (Sandbox Code Playgroud)
在Python 3.6+中,PYTHONIOENCODING
除非将PYTHONLEGACYWINDOWSIOENCODING
envvar设置为非空字符串,否则将忽略envvar 指定的编码以用于交互式控制台缓冲区.
ang*_*son 36
注意:这个答案有点过时(从2008年开始).请小心使用以下解决方案!!
这是一个详细说明问题的页面和解决方案(在页面中搜索将sys.stdout包装到实例中的文本):
这是该页面的代码摘录:
$ 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
?
?
Run Code Online (Sandbox Code Playgroud)
有关该页面的更多信息,非常值得一读.
Gia*_*olà 14
如果你对获得可靠的坏字符表示不感兴趣,可以使用类似的东西(使用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}")
Run Code Online (Sandbox Code Playgroud)
字符串中的错误字符将以Windows控制台可打印的表示形式进行转换.
sor*_*rin 10
下面的代码将使Python输出到控制台,即使在Windows上也是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"
Run Code Online (Sandbox Code Playgroud)
就像 Giampaolo Rodolà 的回答一样,但更肮脏:我真的,真的打算花很长时间(很快)了解编码的整个主题以及它们如何应用于 Windoze 控制台,
目前我只想要 sthg 这意味着我的程序不会崩溃,而且我理解......而且它不涉及导入太多外来模块(特别是我使用的是 Jython,所以有一半的时间是 Python模块实际上并不可用)。
def pr(s):
try:
print(s)
except UnicodeEncodeError:
for c in s:
try:
print( c, end='')
except UnicodeEncodeError:
print( '?', end='')
Run Code Online (Sandbox Code Playgroud)
注意“pr”比“print”更短(并且比“safeprint”更短)......!
小智 6
只需在执行 python 脚本之前在命令行中输入此代码:
chcp 65001 & set PYTHONIOENCODING=utf-8
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
92039 次 |
最近记录: |