如何设置 PYTHONUTF8 环境变量以在 Python 中默认启用 UTF-8 编码?

cos*_*hia 5 python utf-8 python-3.x

Python 3.7 引入了 PYTHONUTF8 环境变量来默认启用 UTF-8 编码。如何从 Python 程序中设置此变量?(我在操作系统的环境变量列表中找不到它。)

wim*_*wim 10

通常您可以使用命令行参数指定它

python3.7 -X utf8
Run Code Online (Sandbox Code Playgroud)

如果要从环境变量启用 UTF-8 模式:

export PYTHONUTF8=1  # linux / macOS
set PYTHONUTF8=1  # windows
Run Code Online (Sandbox Code Playgroud)

它应该在进入Python运行时之前设置。


aba*_*ert 4

要访问环境变量,并在您的平台允许的情况下修改它们(Windows 和所有流行的 Unix 都这样做),只需使用os.environ.

\n\n

但是,这不会有任何好处,除非您尝试为您启动的 Python 子进程设置环境变量。subprocess。Python 在启动时读取其环境变量,使用它们来获取配置信息,并且稍后不会再次检查它们。

\n\n
\n\n

这些环境变量(和命令行标志)的目的是在 shell、启动器脚本等中设置它们,以便在 Python 启动时它们\xe2\x80\x99 可用,而不是从 Python 内部设置它们。

\n\n

通常,如果您需要此设置,您\xe2\x80\x99将在全局范围内需要它,因此您\xe2\x80\x99将希望在您的shell配置文件脚本(对于Linux)、您的操作系统\xe2\x80\中设置它用于环境变量的 x99s GUI(对于 Windows),或两者(对于 macOS\xe2\x80\x94,尽管在 Mac 上,所有内容都已经保证设置为 UTF-8,我相信即使你设法以某种方式打破它,Python 也会忽略它)。

\n\n

你\xe2\x80\x99不会在你现有的环境变量列表中找到这个(除非你\xe2\x80\x99re在一个不寻常的Linux发行版上,它对语言环境设置做了一些奇怪的事情,但需要它的默认Python来忽略它们),但这并不重要;您可以添加任何您想要的环境变量。

\n\n
\n\n

但是,如果您想动态更改内容,虽然您可以通过设置环境变量来做到这一点,但您也不需要这样做。

\n\n

正如文档所解释的,它控制的是设置文件系统编码、首选编码和 stdio 文件编码。

\n\n

前两个,您可以在sys和中调用相同的函数locale随时

\n\n

如果您还想更改 stdio 文件,那么 \xe2\x80\x99s 有点棘手。我相信让动态更改这些文件的编码变得更容易的提案被拒绝或推迟,因此您唯一能做的就是用包裹在同一文件描述符中的新文件对象替换它们,它看起来像这样(暂时未经测试):

\n\n
sys.stdout = open(sys.stdout.fileno(), \'w\', encoding=\'utf-8\', errors=\'surrogateescape\')\nsys.stderr = open(sys.stderr.fileno(), \'w\', encoding=\'utf-8\', errors=\'backslashescape\')\nsys.stdin = open(sys.stdin.fileno(), \'r\', encoding=\'utf-8\', errors=\'surrogateescape\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您\xe2\x80\x99已经将任何内容打印到标准输出或将任何内容输入/通过管道传输到标准输入,您可能需要flush先完成所有内容。

\n\n

我所知道的唯一剩下的问题是sys.argvand os.environwill (至少在 Unix 上)已经用错误的编码进行了解码。在设置默认编码之前,您可以通过重新编码和重新解码来修复参数。我认为这使用了区域设置,所以它看起来像:

\n\n
sys.argv = [arg.encode(locale.getpreferredencoding(), errors=\'surrogateescape\').decode(\'utf8\', errors=\'surrogateescape\') for arg in sys.argv]\n
Run Code Online (Sandbox Code Playgroud)\n\n

修复环境有点棘手,因为如果您尝试改变os.environ它,\xe2\x80\x99s 将执行putenv您不\xe2\x80\x99 不想要的调用。如果这是一个问题,最好的选择可能是制作转码副本environ并将其用于查找,并将其显式传递给子进程等。

\n