如何让IDLE接受Unicode字符粘贴?
我在使用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 个回答
我终于找到了一种方法。因为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
中修改的方法。