标准输入和输出是 Python 中的文件对象。 Python 3 文档说,创建这些对象时,如果encoding
未指定,则locale.getpreferredencoding(False)
调用 if 以获取语言环境的首选编码。
安装 GNU/Linux 时,您的系统应该已经设置了一个或多个“语言环境”(我从您的路径猜测您正在使用某个版本的 GNU/Linux)。在“合理”的设置中,默认语言环境应允许 UTF-8。但是,如果您只进行了“最小”安装(例如作为设置容器的一部分)或类似的安装,那么系统可能已将语言环境设置为"C"
(最终的后备语言环境),它不支持 UTF -8。
仅仅因为您的终端可以接受 UTF-8(如使用echo
UTF-8 字符串所证明的那样),并不意味着Python 知道UTF-8 是可以接受的。如果 Python 看到语言环境设置为,"C"
那么它将假定只允许使用 ASCII,除非另有说明。
locale
您可以通过在 shell 提示符下键入来检查当前语言环境,并通过设置LC_ALL
环境变量来更改它。但是在更改它之前,您必须检查locale -a
您的系统上有哪些可用的语言环境,否则您的更改可能无效,并且您仍然可能获得该"C"
语言环境。如果您的系统没有设置您想要的语言环境,如果您有 root 访问权限,则可以添加它:大多数 GNU/Linux 发行版在您(重新)配置一个名为 的包时提供执行此操作的选项locales
,例如在 Debian/基于 Ubuntu 的发行版sudo dpkg-reconfigure locales
应该会向您展示这些选项。
但有时你会处于尴尬的境地,不得不编写一个 Python 脚本才能在一个没有设置好的语言环境的系统上运行,而且你无能为力,因为你没有 root 并且系统管理员坚持给你绝对的最低限度。 那我们怎么办?
好吧,Python 本身有一些选项。您可以export PYTHONIOENCODING=utf-8
在运行 Python 之前运行,以告诉 Python 无论语言环境如何使用该编码。或者您可以提供pprint
一个参数,设置为您自己使用参数stream=
打开的流(尽管如果您想使用或代替文件,这并不好)。或者您可以升级到 Python 3.7 并使用(但这在原始问题中提到的 Python 3.6 中不起作用)。open()
encoding="utf-8"
sys.stdout
os.popen
sys.stdout.reconfigure(encoding='utf-8')
或者,您可以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)