164

当我尝试在 Windows 控制台中打印 Unicode 字符串时,出现错误。

UnicodeEncodeError: 'charmap' codec can't encode character ....

我认为这是因为 Windows 控制台不接受纯 Unicode 字符。解决这个问题的最佳方法是什么?有什么办法可以让 Python?在这种情况下自动打印 a 而不是失败?

编辑: 我使用的是 Python 2.5。


注意: @LasseV.Karlsen 带有复选标记的答案有点过时(从 2008 年开始)。请谨慎使用下面的解决方案/答案/建议!!

从今天(2016 年 1 月 6 日)起,@JFSebastian 的回答更加相关。

4

14 回答 14

83

更新: Python 3.6实现PEP 528:将 Windows 控制台编码更改为 UTF-8Windows 上的默认控制台现在将接受所有 Unicode 字符。在内部,它使用与下面提到win-unicode-console包相同的 Unicode API 。print(unicode_string)现在应该可以工作了。


我得到一个UnicodeEncodeError: 'charmap' codec can't encode character... 错误。

该错误意味着您尝试打印的 Unicode 字符无法使用当前 ( chcp) 控制台字符编码来表示。代码页通常是 8 位编码,例如cp437只能表示 ~1M Unicode 字符中的 ~0x100 个字符:

>>> u"\N{EURO SIGN}".encode('cp437')
回溯(最近一次通话最后):
...
UnicodeEncodeError:“charmap”编解码器无法在位置 0 编码字符“\u20ac”:
字符映射到

我认为这是因为 Windows 控制台不接受纯 Unicode 字符。解决这个问题的最佳方法是什么?

Windows 控制台确实接受 Unicode 字符,如果配置了相应的字体,它甚至可以显示它们(仅限 BMP)。WriteConsoleW()API 应按照@Daira Hopwood 的回答中的建议使用。win-unicode-console它可以被透明地调用,即,如果你使用package,你不需要也不应该修改你的脚本:

T:\> py -m pip install win-unicode-console
T:\> py -m run your_script.py

请参阅Python 3.4、Unicode、不同语言和 Windows 有什么区别?

有什么办法可以让 Python?在这种情况下自动打印 a 而不是失败?

如果在您的情况下替换所有不可编码的字符就足够了,?那么您可以设置PYTHONIOENCODINGenvvar

T:\> set PYTHONIOENCODING=:replace
T:\> python3 -c "print(u'[\N{EURO SIGN}]')"
[?]

在 Python 3.6+ 中,除非envvar 设置为非空字符串,PYTHONIOENCODING否则交互式控制台缓冲区会忽略 envvar指定的编码。PYTHONLEGACYWINDOWSIOENCODING

于 2015-08-24T07:35:32.270 回答
40

注意:这个答案有点过时(从 2008 年开始)。请谨慎使用以下解决方案!


这是一个详细说明问题和解决方案的页面(在页面中搜索文本Wrapping sys.stdout into an instance):

打印失败 - 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
  Б
  Б

该页面上有更多信息,非常值得一读。

于 2008-08-07T22:32:23.510 回答
30

尽管其他看似合理的答案建议将代码页更改为 65001,但这不起作用。(此外,更改默认编码 usingsys.setdefaultencoding不是一个好主意。)

有关详细信息和有效的代码,请参阅此问题

于 2011-01-09T05:07:56.410 回答
12

如果您对获得坏字符的可靠表示不感兴趣,您可以使用这样的东西(使用 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}")

字符串中的错误字符将转换为可由 Windows 控制台打印的表示形式。

于 2012-05-19T18:48:28.440 回答
10

即使在 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"
于 2010-01-06T13:38:39.843 回答
7

只需在执行 python 脚本之前在命令行中输入此代码:

chcp 65001 & set PYTHONIOENCODING=utf-8
于 2018-10-02T22:11:03.390 回答
6

就像 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='')

注意“pr”的类型比“print”短(并且比“safeprint”的类型短很多)......!

于 2016-03-09T22:14:15.093 回答
3

有点与 JF Sebastian 的回答有关,但更直接。

如果您在打印到控制台/终端时遇到此问题,请执行以下操作:

>set PYTHONIOENCODING=UTF-8
于 2015-12-16T07:53:43.617 回答
3

对于 Python 2 尝试:

print unicode(string, 'unicode-escape')

对于 Python 3 尝试:

import os
string = "002 Could've Would've Should've"
os.system('echo ' + string)

或者试试 win-unicode-console:

pip install win-unicode-console
py -mrun your_script.py
于 2017-08-24T18:00:20.660 回答
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

编辑:更多信息可以在优秀的 Dive into Python 书中找到

于 2008-08-11T17:58:28.733 回答
2

TL;博士:

print(yourstring.encode('ascii','replace'));

我自己遇到了这个问题,正在开发一个 Twitch 聊天 (IRC) 机器人。(Python 2.7 最新版本)

我想解析聊天消息以做出回应...

msg = s.recv(1024).decode("utf-8")

但也可以以人类可读的格式将它们安全地打印到控制台:

print(msg.encode('ascii','replace'));

这更正了机器人抛出UnicodeEncodeError: 'charmap'错误的问题,并将 unicode 字符替换为?.

于 2018-07-01T15:52:05.617 回答
1

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选择 lucida 控制台。

于 2017-05-11T20:08:34.870 回答
0

詹姆斯·苏拉克问道,

有什么方法可以让 Python 自动打印一个 ? 而不是在这种情况下失败?

其他解决方案建议我们尝试修改 Windows 环境或替换 Python 的print()功能。下面的答案更接近于满足苏拉克的要求。

在 Windows 7 下,可以使 Python 3.5 打印 Unicode 而不会抛出 aUnicodeEncodeError如下:

    代替:    print(text)
    替代:     print(str(text).encode('utf-8'))

Python 现在不再抛出异常,而是将不可打印的 Unicode 字符显示为\xNN十六进制代码,例如:

  Halmalo n\xe2\x80\x99\xc3\xa9tait plus qu\xe2\x80\x99un point noir

代替

  Halmalo n'était plus qu'un point noir

当然,在其他条件不变的情况下,后者更可取,但除此之外,前者对于诊断消息是完全准确的。因为它将 Unicode 显示为文字字节值,所以前者还可以帮助诊断编码/解码问题。

注意:上面的str()调用是必需的,否则encode()会导致 Python 拒绝将 Unicode 字符作为数字元组。

于 2016-05-14T17:47:35.337 回答
0

问题在于 Windows 默认编码设置为 cp1252,需要设置为 utf-8。(检查 PEP

使用以下命令检查默认编码:

import locale 
locale.getpreferredencoding()

您可以覆盖区域设置

import os
if os.name == "nt":
    import _locale
    _locale._gdl_bak = _locale._getdefaultlocale
    _locale._getdefaultlocale = (lambda *args: (_locale._gdl_bak()[0], 'utf8'))

来自堆栈链接的引用代码

于 2021-07-24T07:16:22.080 回答