pprint:UnicodeEncodeError:'ascii'编解码器无法编码字符

时间:2017-12-30 13:48:39

标签: python dictionary pprint

这让我发疯了 我试图用一个'é'字符打印一个字典,它把我扔了出去 我'使用Python 3

    from pprint import pprint
    knights = {'gallahad': 'the pure', 'robin': 'the bravé'}
    pprint (knights)

错误

File "/data/prod_envs/pythons/python36/lib/python3.6/pprint.py", line 176, in _format
stream.write(rep)
UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 43: ordinal not in range(128)

我读了Python ASCII文档,但似乎没有一种快速解决方法,除了将dict分开,并通过'.encode'将有问题的值重写为ASCII值,然后重新再次组装字典

有没有什么方法可以让你打印而不把dict分开?

谢谢!

2 个答案:

答案 0 :(得分:4)

这与pprint无关:模块只将格式化字符串转换为另一个字符串,然后将格式化的字符串传递给基础流。因此,当é字符(U + 00E9)写入stdout时会发生错误。

现在它真的取决于底层操作系统和Python解释器的配置。在Linux或其他类Unix系统中,您可以尝试通过在启动Python之前设置环境变量PYTHONIOENCODING来在终端会话中声明UTF-8或Latin1字符集:

$ export PYTHONIOENCODING=Latin1
$ python

(或使用PYTHONIOENCODING=utf8,具体取决于终端或终端窗口的实际编码。)

答案 1 :(得分:0)

标准输入和输出是Python中的文件对象。 The Python 3 documentation says表示,在创建这些对象时,如果未指定encoding,则会调用locale.getpreferredencoding(False)来获取语言环境的首选编码。

在安装GNU / Linux时,您的系统应该已经设置了一个或多个“区域设置”(我从您的路径猜测,您正在使用某些版本的GNU / Linux)。在“明智的”设置中,默认语言环境应允许UTF-8。但是,如果您仅进行了“最小”安装(例如,作为设置容器的一部分)或类似的操作,则系统可能会将语言环境设置为"C"(最终的后备语言环境),不支持UTF-8。

仅仅因为您的 terminal 可以接受UTF-8(如将echo与UTF-8字符串结合使用),并不意味着 Python知道 UTF-8是可以接受的。如果Python看到语言环境设置为"C",则除非另有说明,否则它将假定仅允许ASCII。

您可以通过在shell提示符下键入locale来检查当前语言环境,并通过设置LC_ALL环境变量来更改它。但是在进行更改之前,您必须与locale -a进行检查,以查看系统上可用的语言环境,否则更改可能无效,并且无论如何您都可以获得"C"语言环境。如果尚未使用所需的语言环境来设置系统,则可以在具有root用户访问权限的情况下添加它:大多数GNU / Linux发行版都提供了(重新)配置名为locales的软件包时执行此操作的选项。例如在基于Debian / Ubuntu的发行版上,sudo dpkg-reconfigure locales应该向您显示选项。

但是有时候您将不得不编写一个Python脚本以在尚未使用适当语言环境设置 且没有 您可以这样做,因为您没有root用户,并且sysadmin坚持给您绝对最低的权限。 然后我们该怎么办?

Python本身内有一些选项。您可以在运行Python之前运行export PYTHONIOENCODING=utf-8,以告诉Python使用该编码,而不管语言环境如何。或者,您可以给pprint一个stream=参数,将其设置为使用open()和一个encoding="utf-8"参数打开的流(尽管如果需要,这样做并不好使用sys.stdoutos.popen代替文件)。或者,您可以升级到Python 3.7并使用sys.stdout.reconfigure(encoding='utf-8')(但这在原始问题中提到的Python 3.6中不起作用)。

或者,您可以import codecs并执行w=codecs.getwriter("utf-8")(sys.stdout.buffer),然后将stream=w传递给您的pprint

from pprint import pprint
import sys, codecs
w=codecs.getwriter("utf-8")(sys.stdout.buffer)
d = {"testing": "这是个考验"}
pprint (d, stream=w)