11.1 打开文件
要打开文件,可使用函数open,它位于自动导入的模块io中。函数open将文件名作为唯一必不可少的参数,并返回一个文件对象。如果当前目录中有一个名为somefile.txt的文本文件(可能是使用文本编辑器创建的),则可像下面这样打开它:
>>> f = open('somefile.txt')
文件模式


11.2 文件的基本方法
11.2.1 读取和写入
文件最重要的功能是提供和接收数据。如果有一个名为f的类似于文件的对象,可使用f.write来写入数据,还可使用f.read来读取数据。与Python的其他大多数功能一样,在哪些东西可用作数据方面,也存在一定的灵活性,但在文本和二进制模式下,基本上分别将str和bytes类用作数据。
每当调用f.write(string)时,你提供的字符串都将写入到文件中既有内容的后面。
>>> f = open('somefile.txt', 'w')
>>> f.write('Hello, ')
7
>>> f.write('World!')
6
>>> f.close()
读取也一样简单,只需告诉流你要读取多少个字符(在二进制模式下是多少字节),如下例所示:
>>> f = open('somefile.txt', 'r')
>>> f.read(4)
'Hell'
>>> f.read()
'o, World!'
首先,指定了要读取多少(4)个字符。接下来,读取了文件中余下的全部内容(不指定要读取多少个字符)。请注意,调用open时,原本可以不指定模式,因为其默认值就是'r'。
11.2.2 使用管道重定向输出
在bash等shell中,可依次输入多个命令,并使用管道将它们链接起来,如下所示:
$ cat somefile.txt | python somescript.py | sort
这条管道线包含三个命令。
cat somefile.txt:将文件somefile.txt的内容写入到标准输出(sys.stdout)。
python somescript.py:执行Python脚本somescript。这个脚本从其标准输入中读取,并
将结果写入到标准输出。
sort:读取标准输入(sys.stdin)中的所有文本,将各行按字母顺序排序,并将结果写入到标准输出。
但这些管道字符(|)有何作用呢?脚本somescript.py的作用是什么呢?管道将一个命令的标准输出链接到下一个命令的标准输入。很聪明吧?因此可以认为,somescript.py从其sys.stdin中读取数据(这些数据是somefile.txt写入的),并将结果写入到 sys.stdout(sort将从这里获取数据)。
下面是一个使用sys.stdin的简单脚本(somescript.py)
# somescript.py
import sys
text = sys.stdin.read()
words = text.split()
wordcount = len(words)
print('Wordcount:', wordcount)
cat somefile.txt | python somescript.py的结果如下:
Wordcount: 11
11.2.5 使用文件的基本方法
假设文件somefile.txt包含代码清单如下所示的文本,可对其执行哪些操作呢?
Welcome to this file
There is nothing here except
This stupid haiku
我们来试试前面介绍过的方法,首先是read(n)。
>>> f = open(r'C:\text\somefile.txt')
>>> f.read(7)
'Welcome'
>>> f.read(4)
' to '
>>> f.close()#关闭文件
接下来是read():
>>> f = open(r'C:\text\somefile.txt')
>>> print(f.read())
Welcome to this file
There is nothing here except
This stupid haiku
>>> f.close()
下面是readline():
>>> f = open(r'C:\text\somefile.txt')
>>> for i in range(3):
print(str(i) + ': ' + f.readline(), end='')
0: Welcome to this file
1: There is nothing here except
2: This stupid haiku
>>> f.close()
最后是readlines():
>>> import pprint
>>> pprint.pprint(open(r'C:\text\somefile.txt').readlines())
['Welcome to this file\n',
'There is nothing here except\n',
'This stupid haiku']
请注意,这里我利用了文件对象将被自动关闭这一事实。下面来尝试写入,首先是write(string)。
>>> f = open(r'C:\text\somefile.txt', 'w')
>>> f.write('this\nis no\nhaiku')
13
>>> f.close()
运行上述代码后,这个文件包含的文本如代码清单如下所示:
this
is no
haiku
最后是writelines(list):
>>> f = open(r'C:\text\somefile.txt')
>>> lines = f.readlines()
>>> f.close()
>>> lines[1] = "isn't a\n"
>>> f = open(r'C:\text\somefile.txt', 'w')
>>> f.writelines(lines)
>>> f.close()
运行这些代码后,这个文件包含的文本如代码如下所示:
this
isn't a
haiku
11.3 迭代文件内容
至此,你见识了文件对象提供的一些方法,还学习了如何获得文件对象。一种常见的文件操作是迭代其内容,并在迭代过程中反复采取某种措施。这样做的方法有很多,你完全可以找到自己喜欢的方法并坚持使用。
在本节的所有示例中,我都将使用一个名为process的虚构函数来表示对每个字符或所做的处理,你可以用自己的喜欢的方式实现这个函数。下面是一个简单的示例:
def process(string):
print('Processing:', string)
11.3.1 每次一行
处理文本文件时,你通常想做的是迭代其中的行,而不是每个字符。
with open(filename) as f:
while True:
line = f.readline()
if not line: break
process(line)
11.3.2 读取所有内容
如果文件不太大,可一次读取整个文件;为此,可使用方法read并不提供任何参数(将整个文件读取到一个字符串中),也可使用方法readlines(将文件读取到一个字符串列表中,其中每个字符串都是一行)。
with open(filename) as f:
for char in f.read():
process(char)
with open(filename) as f:
for line in f.readlines():
process(line)
11.3.3 使用 fileinput 实现延迟行迭代
有时候需要迭代大型文件中的行,此时使用readlines将占用太多内存。当然,你可转而结合使用while循环和readline,但在Python中,在可能的情况下,应首选for循环,而这里就属于这种情况。你可使用一种名为延迟行迭代的方法——说它延迟是因为它只读取实际需要的文本部分。
import fileinput
for line in fileinput.input(filename):
process(line)
网友评论