Python中Unicode (UTF-8)文件读写

414

我在理解如何读写文件(Python 2.4)方面遇到了一些困难。

# The string, which has an a-acute in it.
ss = u'Capit\xe1n'
ss8 = ss.encode('utf8')
repr(ss), repr(ss8)
("u'Capit\xe1n'", "'Capit\xc3\xa1n'")
print ss, ss8
print >> open('f1','w'), ss8

>>> file('f1').read()
'Capit\xc3\xa1n\n'

我在我的喜爱编辑器中输入了Capit\xc3\xa1n,并保存在文件f2中。

接着:

>>> open('f1').read()
'Capit\xc3\xa1n\n'
>>> open('f2').read()
'Capit\\xc3\\xa1n\n'
>>> open('f1').read().decode('utf8')
u'Capit\xe1n\n'
>>> open('f2').read().decode('utf8')
u'Capit\\xc3\\xa1n\n'

我到底哪里理解有误?显然我缺少某些重要的魔法(或好的想法)。该如何在文本文件中输入才能得到正确的转换?

我真正无法领会的是,如果从外部获取UTF-8表示时Python不能识别它,那么UTF-8表示的意义是什么。也许我应该只将字符串转储为JSON,然后使用它,因为它具有可转换为ASCII的表示!更重要的是,是否存在这个Unicode对象的ASCII表示,Python可以在从文件中读入时识别并解码?如果有,我该如何获得它?

>>> print simplejson.dumps(ss)
'"Capit\u00e1n"'
>>> print >> file('f3','w'), simplejson.dumps(ss)
>>> simplejson.load(open('f3'))
u'Capit\xe1n'

要理解的重要事情是,u'Capit\xe1n\n'是一个正确的结果,并且该字符串已经包含了你要寻找的特殊字符。它只是用转义序列表示。这里的实质问题与如何读写文件和指定编码实际上没有任何关系,因为代码已经正确地展示了如何做到这一点。 - Karl Knechtel
14个回答

4

\x..序列是Python特有的,不是通用的字节转义序列。

如何输入UTF-8编码的非ASCII字符取决于您的操作系统和/或编辑器。在Windows中这里告诉您如何做。在OS X中,要输入带重音符号的a,您只需按下option + E,然后再按下A,几乎所有的OS X文本编辑器都支持UTF-8。


3

您还可以使用partial函数直接替换原始的open()函数,以便处理Unicode文件。这种解决方案的美妙之处在于,您不需要更改任何旧代码,它是透明的。

import codecs
import functools
open = functools.partial(codecs.open, encoding='utf-8')

1
我正在尝试使用Python 2.7.9解析iCal

from icalendar import Calendar

但是出现了以下错误:

 Traceback (most recent call last):
 File "ical.py", line 92, in parse
    print "{}".format(e[attr])
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 7: ordinal not in range(128)

而且只需要这样修复:

print "{}".format(e[attr].encode("utf-8"))

现在它可以像老板一样打印。

-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接