如何更改 Python IDLE 的默认字符编码?

How to change default character encoding for Python IDLE?

我在 Windows 上使用 Python 3.6。当我运行脚本使用标准Windowsshell(cmd.exe)时,默认文本编码为 stdin/stdout 与 Python 中预期的一样 'utf-8' 3.x:

python -c "import sys; print(sys.stdout.encoding)"
utf-8

然而,在 IDLE shell 上使用相同的命令会导致不同的结果,这显然很烦人,尤其是对于使用 IDLE 作为第一步的初学者 IDE

>>> import sys; print(sys.stdout.encoding)
cp1252

正好IDLE定义了PseudoOutputFilePseudoInputFile类来包裹stdout/stdin。这些 类 包括一个隐藏的 _encoding 属性,可用于根据需要切换编码

>>> sys.stdout._encoding = 'utf-8'
>>> print(sys.stdout.encoding)
utf-8

但是每次启动脚本时都会取消此设置,因为在 运行 运行模块时 IDLE 会重新启动其 shell。是否有任何长期解决方案来更改 stdin/stdout 的 IDLE 默认编码?

对于 2.7、3.5,您显示的命令行响应对我来说是 cp437 - IBM PC 或 DOS 编码。 Windows 控制台的输出仅限于基本多语言平面 (BMP) Unicode 字符的子集。

对于 3.6,Python 对 Windows 控制台的处理得到了显着改进,可以使用 utf-8 并可能打印任何 unicode 字符,具体取决于字体可用性。

对于所有当前版本,IDLE 还为我报告 cp1252(拉丁语 1)。由于尝试获取系统编码,我不知道为什么会有所不同。但它几乎没有任何区别,因为它是一个虚拟值或假值。对我来说,这是具有欺骗性的,因为非 latin1 字符不能用 latin1 编码,而所有 BMP 字符都可以在 IDLE 中打印。所以想换一个。

当(unicode)字符串被写入sys.stdout(通常使用print)时,字符串对象在用户进程中被pickle为字节,通过套接字(实现细节可能发生变化)发送到IDLE处理,并解封回一个字符串对象。效果就好像字符串是用 non-lossy utf 编码之一编码和解码的。 UTF-32 可能是最接近酸洗的。

IDLE 进程调用 tkinter text.insert(index, string),它要求 tk 将字符串插入到小部件中。但这只适用于 BMP 字符。最终效果就好像输出编码是 ucs-2,尽管我相信 tk 在内部使用截断的 utf-8。

同样,在shell或编辑器中输入的任何BMP字符,显示后都可以发送给用户进程stdin。

无论如何,更改pseudofile.encoding没有效果,这就是issue 9290

的这部分补丁将其设为read-only的原因
-        self.encoding = encoding
+        self._encoding = encoding
+
+    @property
+    def encoding(self):
+        return self._encoding

开头的下划线表示 _encoding 是用户应忽略的私有(未隐藏)实现细节。