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

时间:2018-03-13 11:22:06

标签: python character-encoding stdout python-idle

我在Windows上使用Python 3.6。当我使用标准Windows shell( cmd.exe )运行脚本时, stdin / stdout 的默认文本编码是{3}中的'utf-8'。 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。是否有任何长期解决方案可以更改IDLE的 stdin / stdout 的默认编码?

1 个答案:

答案 0 :(得分:1)

对于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)时,字符串对象在用户进程中被腌制为字节,通过套接字(实现详细信息可能会发生变化)发送到IDLE进程,并且未打开回到一个字符串对象。效果就好像字符串是用非损耗的utf编码之一编码和解码的。 UTF-32可能是最接近酸洗的。

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

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

无论如何,更改pseudofile.encoding没有效果,这就是为什么它被issue 9290

的补丁的这一部分设为只读的原因
-        self.encoding = encoding
+        self._encoding = encoding
+
+    @property
+    def encoding(self):
+        return self._encoding

初始下划线表示_encoding是一个私有(非隐藏)实现细节,应由用户忽略。