{{ cat }}'s docs

3.1.0 如何读取文件


0. 目标

某文本文件编码格式已知(如UTF-8, GBK, BIG5), 在python2和python3中分别如何读取该文件。
但我们知道,在python2和python3间,python2中的str和unicode分别转为python3中的bytes和str


1. 编码简介

因为当时计算机在美国发明,美国人发明的ASCII码来表明文本,所以当时只需要有一个str格式就好,可以直接存入文本,而后期随着计算机技术的普及,显然ASCII码无法满足需要,于是出现了流行广泛的unicode,而unicode只是一种符号集,它规范了符号的二进制代码,但是并没有规范这个二进制码如何去保存,所以相应的就出现了UTF-8这种unicode的具体实现方案,UTF-8这种方案的优点在于,它是一种变长的编码方式,英文字母需要的编码位数小,则储存空间占用小,而汉字需要的编码位数多,则储存空间相应也多。这样就避免了unicode的储存空间浪费问题。

总结:

  • 最先出现ASCII码,只适用于英文
  • 一种包含世界上所有符号的编码unicode
  • 一种unicode的最流行的互联网实现方式UTF-8

我们一般在读取字符串的时候将其转化为unicode,在储存字符串时,将其转化为str


2. 编码与解码

# 创建一个中文的unicode字符串
>>> c = u'你好'
>>> type(c)
unicode
>>> c
u'\u4f60\u597d'

# 编码与解码
>>> c.encode('utf8')
'\xe4\xbd\xa0\xe5\xa5\xbd'

>>> c.encode('gbk')
'\xc4\xe3\xba\xc3'

>>> '\xc4\xe3\xba\xc3'.decode('gbk')
u'\u4f60\u597d'

>>> '\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf8')
u'\u4f60\u597d'

>>> print u'\u4f60\u597d'
你好


# 只有encode之后成为一个str,才可以用于储存
>>> type(c.encode('utf8'))
str

3. python2中字符串在文件中的写入和写出

# python2中的字符串写入
>>> f = open('/tmp/py2.txt', 'w')

>>> s = u'你好,这是python2'

>>> f.write(s.encode('utf8'))

>>> f.close()

# python2中的字符串读取
>>> f = open('/tmp/py2.txt', 'r')

>>> d = f.read()

>>> d
'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe8\xbf\x99\xe6\x98\xafpython2'

>>> d.decode('utf8')
u'\u4f60\u597d\uff0c\u8fd9\u662fpython2'

>>> print u'\u4f60\u597d\uff0c\u8fd9\u662fpython2'
你好,这是python2

4. python3中字符串在文件中的写入和写出

# python3 中的bytes(原str)和str(原unicode)
>>> type(b'abc')
bytes

>>> type('abc')
str

# python3中的字符串写入,即使mode不指定t,它默认也是t(text)模式
>>> f = open('/tmp/py3.txt', 'wt', encoding='utf8')

>>> s = '你好,这是python3'

>>> f.write('你好,这是python3')
12

>>> f.close()

# python3中的字符串读取
>>> f = open('/tmp/py3.txt', 'rt', encoding='utf8')

>>> d = f.read()

>>> d
'你好,这是python3'