IPython中的输入编码奇怪问题

13 投票
3 回答
8999 浏览
提问于 2025-04-15 19:16

我在Windows XP SP3上用的是Python 2.6和最新的IPython,现在有两个问题。第一个问题是,在IPython里,我不能直接输入Unicode字符串,这导致我无法打开那些名字里有非拉丁字母的文件。让我给你演示一下。在普通的Python环境下,这样是可以的:

>>> sys.getdefaultencoding()
'ascii'
>>> sys.getfilesystemencoding()
'mbcs'
>>> fd = open(u'm:/Блокнот/home.tdl')
>>> print u'm:/Блокнот/home.tdl'
m:/Блокнот/home.tdl
>>>

顺便说一下,这里是西里尔字母。而在IPython里,我得到的是:

In [49]: sys.getdefaultencoding()
Out[49]: 'ascii'

In [50]: sys.getfilesystemencoding()
Out[50]: 'mbcs'

In [52]: fd = open(u'm:/Блокнот/home.tdl')
---------------------------------------------------------------------------
IOError                                   Traceback (most recent call last)

C:\Documents and Settings\andrey\<ipython console> in <module>()

IOError: [Errno 2] No such file or directory: u'm:/\x81\xab\xae\xaa\xad\xae\xe2/home.tdl'

In [53]: print u'm:/Блокнот/home.tdl'
-------------->print(u'm:/Блокнот/home.tdl')
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (15, 0))

---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)

C:\Documents and Settings\andrey\<ipython console> in <module>()

C:\Program Files\Python26\lib\encodings\cp866.pyc in encode(self, input, errors)
     10
     11     def encode(self,input,errors='strict'):
---> 12         return codecs.charmap_encode(input,errors,encoding_map)
     13
     14     def decode(self,input,errors='strict'):

UnicodeEncodeError: 'charmap' codec can't encode characters in position 3-9: character maps to <und

In [54]:

第二个问题虽然没有那么让人沮丧,但还是麻烦。当我尝试打开一个文件,并且把文件名作为非Unicode字符串传入时,它就是打不开。我必须强制把字符串从OEM字符集解码,才能打开文件,这样做真的很不方便:

>>> fd2 = open('m:/Блокнот/home.tdl'.decode('cp866'))
>>>

也许这和我的区域设置有关,我也不太清楚,因为我甚至不能从控制台复制粘贴西里尔字母的文本。我在区域设置里到处都设置了“俄语”,但似乎并没有什么用。

3 个回答

0

我也遇到了希腊语输入的问题,这个来自launchpad的补丁对我也有效。

谢谢。

1

有点奇怪的是,这样做是有效的:

fd = open('m:/Блокнот/home.tdl')

或者:

fd = open('m:/Блокнот/home.tdl'.encode('utf-8'))

这个方法可以绕过ipython的一个小问题,通过将字符串作为原始的UTF-8编码字节串输入。这样,ipython就不会对它做什么奇怪的处理。然后你可以选择把它编码成unicode字符串,接着继续你的工作。

12

是的。在控制台输入Unicode字符总是会遇到问题,通常最好避免这样做。不过,IPython在这方面特别糟糕。它会把你在控制台输入的字符当作ISO-8859-1编码来处理,而不管你实际使用的是什么编码。

现在,你需要这样输入:u'm:/\u0411\u043b\u043e\u043a\u043d\u043e\u0442/home.tdl'

撰写回答