如何让IDLE接受Unicode字符粘贴?

3 投票
1 回答
1654 浏览
提问于 2025-04-18 16:01

我在使用IDLE这个工具时,常常想把一个Unicode字符串粘贴到窗口里。看起来粘贴是成功的,但马上就会出现错误。不过,输出的时候显示同样的字符却没有问题。

>>> c = u'ĉ'
Unsupported characters in input

>>> print u'\u0109'
ĉ

我猜测输入窗口就像大多数Windows程序一样,内部使用的是UTF-16编码,能够处理完整的Unicode字符集;问题在于,IDLE总是把所有输入强制转换为默认的mbcs编码,而任何不在这个编码范围内的字符都会被拒绝。

有没有办法设置或者让IDLE接受完整的Unicode字符集作为输入呢?

Python 3.2在这方面处理得好多了,能轻松应对我输入的任何内容。

我知道我可以把代码保存为UTF-8格式的文件然后导入,但我希望能在交互窗口中直接使用Unicode字符。

1 个回答

2

我终于找到了一种方法。因为IDLE的源代码是分发包的一部分,所以你可以做几个简单的修改来启用这个功能。这些文件通常可以在 C:\Python27\Lib\idlelib 找到。

第一步是防止IDLE试图把那些漂亮的Unicode字符编码成一个无法处理它们的字符集。这是由 IOBinding.py 控制的。编辑这个文件,找到 if sys.platform == 'win32': 之后的部分,然后把这一行注释掉:

#encoding = locale.getdefaultlocale()[1]

接下来在它后面添加这一行:

encoding = 'utf-8'

我本来希望能通过环境变量之类的方式来覆盖这个设置,但 getdefaultlocale 直接调用了一个Win32函数,这个函数获取的是全局配置的Windows mbcs编码。

这只是解决问题的一半,现在我们需要让命令行解释器识别输入的字节是UTF-8编码的。看起来没有办法将编码传递给解释器,所以我想出了一个大招。也许有耐心的人能想出更好的方法,但目前这个方法是有效的。输入是在 PyShell.py 中的 runsource 函数里处理的。把以下内容改成:

    if isinstance(source, types.UnicodeType):
        from idlelib import IOBinding
        try:
            source = source.encode(IOBinding.encoding)
        except UnicodeError:
            self.tkconsole.resetoutput()
            self.write("Unsupported characters in input\n")
            return

改成:

    from idlelib import IOBinding  # line moved
    if isinstance(source, types.UnicodeType):
        try:
            source = source.encode(IOBinding.encoding)
        except UnicodeError:
            self.tkconsole.resetoutput()
            self.write("Unsupported characters in input\n")
            return
    source = "#coding=%s\n%s" % (IOBinding.encoding, source)  # line added

我们利用了 PEP 263 来为提供给解释器的每一行输入指定编码。

更新: 在Python 2.7.10 中,不再需要在 PyShell.py 中做这个修改,只要编码设置为 utf-8 就可以正常工作。不幸的是,我还没有找到绕过 IOBinding.py 中修改的方法。

撰写回答