python——文件和流
1. 打开文件的方式
open函数用来打开文件,语法如下:
open (name[,mode[,buffering]])
open('test.txt'.r)
open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象。模式(mode)和缓冲(buffering)参数都是可选的。
以下介绍open函数的模式和缓冲函数
1.1 文件模式
'r' :读模式
'w':写模式
'a':追加模式
'b':二进制模式
'+':读/写模式
‘b’模式改变处理文件的方法。用于处理一些其他类型的文件(二进制文件),比如声音剪辑或者图像,那么应该在的模式参数中增加‘b’。参数‘rb’可以用来读取一个二进制文件。
1.2 缓冲
open函数的第3个参数(可选)控制文件的缓冲。如果参数是0(或者False),I/O(输入输出流)就是无缓冲的(所有的读写操作都针对硬盘);如果是1(或者是true),
I/O就是有缓冲的(意味着python使用内存来代替硬盘,让程序变得更快,只用使用flush或者close是才会更新硬盘上的数据)。大于1的数字代表缓冲区的大小(单位字节),-1
(或者任何负数)代表使用默认的缓冲区大小。
2.基本的文件方法
打开文件的方法已经介绍了,那么下一步就是用他们做些有用的事。接下来会介绍文件对象(和一些类文件对象,有时候称为流)的一些基本方法。
2.1 读和写
文件(或流)最重要的能力是提供或者接收数据。如果有一名字为f的类文件对象,那么就可以使用f.write方法和f.read方法(以字符串形式)写入和读取数据。
每次调用f.write(string)时,所提供的参数string都会被追加到文件中已存在部分的后面
f = open("somefile.txt", "w") f.write('Hello, ') f.write('Python!') f.close() -------- 结果: Hello,Python!
读文件很简单,只要记得告诉流要读多少字符(字节)即可。
如下:
1 f = open("somefile.txt", "r") 2 print(f.read(4)) 3 print(f.read()) 4 f.close() 6 ------------ 7 结果: 8 D:\Python27\python.exe D:/pythonwork/test01/file_1.py 9 hell 10 o, python!
注意:在调用open时可以省略模式说明,因为‘r’是默认的。
**随机访问
以上的例子把文件当成流来操作,也就是说只能按照从头到尾的顺序读数据。实际上在文件中随意移动读取文件位置也是可以的,可以使用类文件对象的方法seek和tell来直接访问感兴趣的部分(这种方法称为随机访问)。
seek(offset[,whence]):这个方法把当前位置(进行读和写的位置)移动到offest和whence定义的位置。offset类是一个字节(字符)数,表示偏移量。whence默认是0,表示偏移量是从文件开头开始计算的(偏移量必须是非负的)。whence可能被设置为1(相对于当前位置的移动,此时偏移量offset可以是负的)或者2(相对于文件结尾的移动)
例子如下:
f = open("somefile.txt", "w") f.write('0123456789') f.seek(5) f.write("hello, python!") f.close() f = open("somefile.txt", "r") print(f.read()) ------------------------ 结果: D:\Python27\python.exe D:/pythonwork/test01/file_1.py 01234hello, python!
tell方法返回当前文件的位置如下列所示:
f = open("somefile.txt", "r") print(f.read(3)) print(f.read(2)) print(f.tell()) --------- 结果: D:\Python27\python.exe D:/pythonwork/test01/file_1.py 012 34 5
注意:f.tell方法返回的数字在这种情况下是一个长整数。但不是所有的情况都是这样的。
2.2 读写行
可以使用file.readline读取单独的一行。readline方法可以读取一个文件中的所有行并将其作为列表返回。
writeline方法和readline方法相反:传给它一个字符串的列表(实际上任何序列或者可迭代的对象都行),它会把所有的字符串写入文件(或流)。注意,程序不会增加新行,需要自己添加。
注意:在使用其他的符号作为换行符的平台上,用\r(Mac)和\r\n(Windows中)代替\n。
2.3 关闭文件
应该牢记使用close方法关闭文件。
事实上有专门为这种情况设计的语句,即with语句:
with open("somefile.txt") as somefile:
do_something(somefile)
with语句可以打开文件并将其赋值到变量上(somefile),之后就可以将数据写入语句提中的文件(或执行其他操作)。文件在语句结束后会被自动关闭,即使是由异常引起的结束也是如此。
***上下文管理器
with语句实际上是很通用的结构,允许使用所谓的上下文管理器(context manager)。上下文管理器是一种支持_enter_和_exit_这两个方法的对象。
_enter_方法不带参数,它在进入with语句块时被调用,返回值绑定到在as关键字之后的变量。
2.4 使用基本文件方法
1 import pprint 2 3 4 with open("somefile.txt") as somefile: 5 s1 = somefile.read(7) 6 print(s1) 7 s2 = somefile.read(4) 8 print(s2) 9 10 11 with open("somefile.txt") as somefile: 12 s3 = somefile.read() 13 print(s3) 14 15 16 with open("somefile.txt") as somefile: 17 for i in range(3): # 循环三次 18 print('%s: %s'%(str(i), somefile.readline().strip())) 19 20 21 print(pprint.pprint(open("somefile.txt").readlines())) 22 23 24 # 写文件 25 with open("somefile.txt", "w") as somefile: 26 somefile.write("this\nis no\nhaiku")
结果:
D:\Python27\python.exe D:/pythonwork/test01/flie_2.py
this
is
no
this
is no
haiku
0: this
1: is no
2: haiku
['this\n', 'is no\n', 'haiku']
None
修改文本文件案例
1 with open("somefile.txt", "r+") as somefile: 2 lines = somefile.readlines() 3 lines[1] = "isn't b\n" 4 somefile.writelines(lines)
3.对文件内容进行迭代
3.1 按字节处理
最常见的对文件内容进行迭代的方法是在while循环中使用read方法。如下例子:
1 # 定义一个表达函数 2 def process(string): 3 print("Processing: ", string) 4 5 6 with open("somefile.txt", "r") as somefile: 7 char = somefile.read(1) 8 while char: 9 process(char) 10 char = somefile.read(1)
可以看到,赋值语句char =f.read(1)被重复的使用,代码重复通常被认为是一件坏事。为了避免这种情况,可以使用while true/break语句。
1 with open("somefile.txt", "r") as somefile: 2 while True: 3 char = somefile.read(1) 4 if not char: 5 break 6 process(char)
3.2 按行操作
在while中使用readline
1 with open("somefile.txt", "r") as somefile: 2 while True: 3 line = somefile.readline().strip() 4 if not line: 5 break 6 process(line)
用readlines迭代行
1 with open("somefile.txt", "r") as somefile: 2 for line in somefile.readlines(): 3 process(line.strip())
3.3 使用fileinput实现懒惰行迭代
1 for line in fileinput.input("somefile.txt"): 2 process(line)
3.4 文件迭代器
对文件进行迭代而不使用变量存储文件对象
1 for line in open("somefile.txt"): 2 process(line)
可以对文件迭代器执行和普通迭代器相同的操作。如下:
1 with open("somefile2.txt", 'r+') as somefile: 2 somefile.write('First line\n') 3 somefile.write('Second line\n') 4 somefile.write('Third line\n') 5 lines = somefile 6 print(lines) 7 8 # 将文件内容转换为list 9 lines = list(open("somefile2.txt")) 10 print(lines) 11 12 first, second, third = open("somefile2.txt") 13 print(first) 14 print(second) 15 print(third)
结果:
D:\Python27\python.exe D:/pythonwork/test01/flie_2.py
['First line\n', 'Second line\n', 'Third line\n']
First line
Second line
Third line
在这个例子中,注意下面的几点很重要。
- 使用print来向文件内写入内容,这会在提供的字符串后面增加新的行。
- 使用序列来对一个打开的文件进行解包操作,把每行都放入一个单独的变量中(这么做是很有使用性的,因为一般不知道文件中有多少行,但它演示了文件对象的“迭代性”)
- 在写文件后关闭文件,是为了确保数据被更新到硬盘中。建议使用with open(filename) as filename: