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

7 浏览
0 Comments

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

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

# 这个字符串中含有一个带重音符号的字母a。

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化的表示!更重要的是,有没有一种ASCII表示可以让Python在从文件中读取时识别和解码?如果有,我该如何获得它?

>>> print simplejson.dumps(ss)

'"Capit\u00e1n"'

>>> print >> file('f3','w'), simplejson.dumps(ss)

>>> simplejson.load(open('f3'))

u'Capit\xe1n'

0
0 Comments

在Python3中,通过在open()函数中添加encoding='utf-8'参数,可以实现对文件进行Unicode(UTF-8)的读写。这是因为Python3的open()函数增加了encoding参数,用于指定文件的编码方式。默认情况下,编码方式是平台相关的,但可以使用Python支持的任何文本编码。通过将encoding='utf-8'添加为open()函数的参数,可以实现文件的读写都以utf-8编码方式进行。

在Python2中,可以使用codecs.open('somefile', encoding='utf-8')来实现类似的功能。

总结起来,Python3中通过在open()函数中添加encoding='utf-8'参数,可以实现对文件的Unicode(UTF-8)读写,而在Python2中可以使用codecs.open()函数来实现。

0
0 Comments

Unicode (UTF-8) 在 Python 中读写文件的问题及解决方法

在Python中,Unicode (UTF-8) 的编码格式在读写文件时可能会出现一些问题。本文将介绍问题的原因以及解决方法。

问题的原因是,当使用类似于u'Capit\xe1n\n'这样的表示方法时,在Python 3.x中应该只是'Capit\xe1n\n',并且在Python 3.0和3.1版本中必须使用后一种表示方法。其中的\xe1表示一个字符,\x是一个转义序列,表示e1是一个十六进制数。

当我们将Capit\xc3\xa1n写入文件时,实际上文件中包含的是\xc3\xa1。这是8个字节,代码会将其全部读取。我们可以通过显示结果来验证这一点:

# Python 3.x - 以字节而不是文本的形式读取文件,确保我们看到原始数据
open('f2', 'rb').read()
b'Capit\\xc3\\xa1n\n'
# Python 2.x
open('f2').read()
'Capit\\xc3\\xa1n\n'

相反,我们可以在文本编辑器中直接输入像á这样的字符,编辑器会自动将其转换为UTF-8编码并保存。

在Python 2.x中,一个包含这些反斜杠转义序列的字符串可以使用string_escape编解码器进行解码:

# Python 2.x
'Capit\\xc3\\xa1n\n'.decode('string_escape')

结果是一个以UTF-8编码的str,其中带有重音的字符由原始字符串中的\\xc3\\xa1表示。要获得unicode结果,需要再次使用UTF-8进行解码。

在Python 3.x中,string_escape编解码器被unicode_escape取代,并且严格执行以下规则:只能将str编码为bytes,将bytes解码为str。为了处理转义序列,unicode_escape需要以bytes开头(反之亦然,它会将转义序列添加进去),然后将结果中的\xc3\xa1视为字符转义而不是字节转义。因此,我们需要进行更多的操作:

# Python 3.x
'Capit\\xc3\\xa1n\n'.encode('ascii').decode('unicode_escape').encode('latin-1').decode('utf-8')

那么,为什么要使用UTF-8编码格式,而Python却可以使用它来读取文件呢?换句话说,是否存在某种ASCII表示形式,Python可以将\xC3读取为1个字节?

关于你的“那么,为什么要使用…”的问题的答案是“Mu.”(因为Python可以读取以UTF-8编码的文件)。至于你的第二个问题:\xC3不是ASCII字符集的一部分。也许你是指“8位编码”。你对Unicode和编码的概念有些混淆,没关系,很多人都有这样的问题。

建议阅读这篇文章作为入门:[joelonsoftware.com/articles/Unicode.html](http://www.joelonsoftware.com/articles/Unicode.html)

注意:u'\xe1'是一个Unicode码点[U+00e1](http://codepoints.net/U+00e1),它可以根据字符编码使用1个或多个字节进行表示(在UTF-8中是2个字节)。b'\xe1'是一个字节(数字225),它可以根据所使用的字符编码来解码成一个字母,例如在cp1251中是[б (U+0431)](http://codepoints.net/U+0431),在cp866中是[с (U+0441)](http://codepoints.net/U+0441)等。

令人惊讶的是,有多少英国程序员说“只使用ascii”,然后却没有意识到£符号不属于ascii字符集。他们大多不知道ascii!=本地代码页(即latin1)。

对于你最后的问题,在Python 3.x中,将字节写入文件会导致错误消息“write() argument must be str, not bytes”,无论是在Python 2还是Python 3.7中都是如此。

是的,在Python 3.x中,对字符串使用.encode将产生一个bytes对象,只能将其写入以二进制模式打开的文件中。在Python 2.x中应该可以正常工作,因为2.x版本对文本的处理有错误,bytes被假装成字符串(在2.7中,我不确定这个错误从哪个版本开始出现,str实际上是bytes的别名,而unicode是真正的字符串类型)。

0
0 Comments

Python中读写Unicode(UTF-8)文件的原因是为了处理编码问题。如果使用.encode.decode方法,可能会导致混乱和错误。解决方法是在打开文件时指定编码,可以使用io.open函数或codecs.open函数。

在Python 2.6之后的版本中,可以使用io.open函数指定文件的编码。例如,如果文件编码为UTF-8,可以使用以下代码打开文件:

import io
f = io.open("test", mode="r", encoding="utf-8")

然后,使用f.read方法读取文件,返回一个解码后的Unicode对象。例如:

f.read()  # 返回 u'Capit\xe1l\n\n'

在Python 3.x中,io.open函数是内置的open函数的别名,支持encoding参数。在Python 2.x中,open函数不支持encoding参数。另外,也可以使用codecs.open函数来打开文件,该函数是标准库模块codecs中的函数。例如:

import codecs
f = codecs.open("test", "r", "utf-8")
f.read()  # 返回 u'Capit\xe1l\n\n'

需要注意的是,使用codecs.open函数可能会在混合使用read()readline()方法时出现问题。

此外,codecs.open函数也可以与with open(...):语法结合使用,确保在完成操作后自动关闭文件。例如:

with codecs.open(...) as f:
    # 文件操作

如果文件可能包含BOM(字节顺序标记),可以使用encoding="utf-8-sig"。例如,在Python 2.7中使用codecs.open函数打开文件:

codecs.open(file, 'w', 'utf-8-sig')

以上是关于在Python中读写Unicode(UTF-8)文件的原因和解决方法的说明。这些方法可以有效地处理编码问题,确保文件的正确读写。

0