7.1 文件基本操作
>>> s = 'Hello world\n文本文件的读取方法\n文本文件的写入方法\n'
>>> with open('sample.txt','w') as fp: #默认使用cp936编码
... fp.write(s)
...
32
>>> with open('sample.txt') as fp: #默认使用cp936编码
... print(fp.read())
...
Hello world
文本文件的读取方法
文本文件的写入方法
例 7-4 移动文件指针。
√ Python 2.x和Python 3.x对于seek()方法的理解和处理是一致的,都是把文件指针定位到文件指定字节的位置上。但是由于对中文的支持程度不一样,可能会导致在Python 2.x和Python 3.x中的运行结果有所不同。例如下面的代码实在Python 3.x中运行的,当遇到无法解码的字符会抛出异常。
>>> s = '中国山东烟台SDIBT'
>>> fp = open(r'D:\sample.txt','w')
>>> fp.write(s)
11
>>> fp.close()
>>> fp = open(r'D:\sample.txt','r')
>>> print(fp.read(3))
中国山
>>> fp.seek(2) #移动指针
2
>>> print(fp.read(1))
国
>>> fp.seek(13)
13
>>> print(fp.read(1))
D
>>> fp.seek(3)
3
>>> print(fp.read(1))
Traceback (most recent call last):
File "", line 1, in
UnicodeDecodeError: 'gbk' codec can't decode byte 0xfa in position 0: illegal multibyte sequence
#Python 2.x是以字节为单位,Python 3.x是以字符为单位
例 7.2 读取文本文件data.txt(文件中每行存放一个整数)中所有整数,将其按升序排序后再写入文本文件data_asc.txt中。
with open('data.txt','r') as fp:
data = fp.readlines()
data = [int(line.strip()) for line in data]
data.sort()
data = [str(i) + '\n' for i in data]
with open('data_asc.txt','w') as fp:
fp.writelines(data)
7.3 二进制文件操作案例精选
>>> import pickle
>>>
>>> i = 13000000
>>> a = 99.056
>>> s = '中国人民123abc'
>>> lst = [[1,2,3],[4,5,6],[7,8,9]]
>>> tu = (-5,10,8)
>>> coll = {4,5,6}
>>> dic = {'a':'apple','b':'banana','g':'grape','o':'orange'}
>>> data = [i,a,s,lst,tu,coll,dic]
>>>
>>> with open('sample_pickle.dat','wb') as f:
... try:
... pickle.dump(len(data),f) #表示后面要写入数据的个数
... for item in data:
... pickle.dump(item,f)
... except:
... print('写文件异常!') #如果写文件异常,则跳到此处执行
例 7.9 读取二进制文件。
>>> import pickle
>>>
>>> i = 13000000
>>> a = 99.056
>>> s = '中国人民123abc'
>>> lst = [[1,2,3],[4,5,6],[7,8,9]]
>>> tu = (-5,10,8)
>>> coll = {4,5,6}
>>> dic = {'a':'apple','b':'banana','g':'grape','o':'orange'}
>>> data = [i,a,s,lst,tu,coll,dic]
>>>
>>> with open('sample_pickle.dat','wb') as f:
... try:
... pickle.dump(len(data),f) #表示后面要写入数据的个数
... for item in data:
... pickle.dump(item,f)
... except:
... print('写文件异常!') #如果写文件异常,则跳到此处执行
...
>>> import pickle
>>> with open('sample_pickle.dat','rb') as f:
... n = pickle.load(f) #读出文件的数据个数
... for i in range(n):
... x = pickle.load(f)
... print(x)
...
13000000
99.056
中国人民123abc
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
(-5, 10, 8)
{4, 5, 6}
{'a': 'apple', 'b': 'banana', 'g': 'grape', 'o': 'orange'}
例 7-10 使用struct模块写入二进制文件。
>>> n = 1300000000
>>> x = 96.45
>>> b = True
>>> s = 'a1@中国'
>>> sn = struct.pack('if?',n,x,b) #序列化
>>> f = open('sample_struct.dat','wb')
>>> f.write(sn)
9
>>> f.write(s.encode()) #字符串直接编码为字节串写入
9
>>> f.close()
>>>>
>>> import struck
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'struck'
>>> import struct
>>> f = open('sample_struct.dat','rb')
>>> sn = f.read(9)
>>> tu = struct.unpack('if?',sn)
>>> print(tu)
(1300000000, 96.44999694824219, True)
>>> n,x,bl = tu
>>> print('n = ',n)
n = 1300000000
>>> print('x = ',x)
x = 96.44999694824219
>>> print('bl = ',bl)
bl = True
>>> s = f.read(9).decode()
>>> f.close()
>>> print('s = ',s)
s = a1@中国
7.3.3 使用shelve序列化
>>> import shelve
>>> zhangsan = {'age':38,'Sex':'Male','address':'SXLF'}
>>> lisi = {'age':40,'sex':'Male','qq':'1234567','tel':'7654321'}
>>> with shelve.open('shelve_test.dat') as fp:
... fp['zhangsan'] = zhangsan #以字典形式把数据写入文件
... fp['lisi'] = lisi
... for i in range(5):
... fp[str(i)] = str(i)
...
>>> with shelve.open('shelve_test.dat') as fp:
... print(fp['zhangsan'])
... print(fp['zhangsan']['age'])
... print(fp['lisi']['qq'])
... print(fp['3'])
...
{'age': 38, 'Sex': 'Male', 'address': 'SXLF'}
38
1234567
3
7.3.4 使用marshal序列化
Python标准库marshal也可以进行对象的序列化和反序列化。
>>> import marshal #导入模块
>>> x1 = 30
>>> x2 = 5.0
>>> x3 = [1,2,3]
>>> x4 = (4,5,6)
>>> x5 = {'a':1,'b':2,'c':3}
>>> x6 = {7,8,9}
>>> x = [eval('x'+str(i)) for i in range(1,7)]
>>> x
[30, 5.0, [1, 2, 3], (4, 5, 6), {'a': 1, 'b': 2, 'c': 3}, {8, 9, 7}]
>>> with open('test.dat','wb') as fp:
... marshal.dump(len(x),fp) #先写入对象个数
... for item in x:
... marshal.dump(item,fp)
...
5
5
9
20
17
26
20
>>> with open('test.dat','rb') as fp: #打开二进制文件
... n = marshal.load(fp) #获取对象个数
... for i in range(n):
... print(marshal.load(fp)) #反序列化,输出结果
...
30
5.0
[1, 2, 3]
(4, 5, 6)
{'a': 1, 'b': 2, 'c': 3}
{8, 9, 7}