使用 Python 迭代多个输入流中的行
Python 内置的 **open()** 函数以读/写模式打开一个文件,并在其上执行读/写操作。要对多个文件进行批量处理,需要使用 Python 标准库的 **fileinput** 模块。此模块提供了一个 Fileinput 类,具有迭代文件的功能。该模块还定义了用于相同目的的辅助函数。
此模块的主要接口是 **input()** 函数。此函数返回 Fileinput 类的实例。
fileinput.input(files, inplace, mode)
files 参数是一个或多个要逐个读取的文件的名称。每个文件充当一个生成器,并且可以使用 for 循环对其进行迭代。文件中每一行都将在 Python 控制台上打印。
>>> for line in fileinput.input('data.txt'): print (line)
files 参数可以是一个包含多个文件的元组。文件的内容将依次显示。
>>> for line in fileinput.input(files=('a.txt', 'b.txt')): print (line)
Fileinput 类也可以在 with 语句中用作上下文管理器。
>>> with fileinput.input(files=('a.txt', 'b.txt')) as f: for line in f: print (line)
fileinput 模块在其内部定义了以下函数。
序号 | 函数 & 描述 |
---|---|
1 | filename() 返回当前正在读取的文件的名称。 |
2 | fileno() 返回文件描述符整数。 |
3 | lineno() 返回正在读取的文件的行号。该数字是累积计数。 |
4 | filelineno() 仅返回当前文件的行号。 |
5 | isfirstline() 如果正在读取当前文件的第一行,则返回 true,否则返回 false |
以下语句打印文件中每一行以及行号
>>> for line in fileinput.input('books.py'): print ('{}->{}'.format(fileinput.filelineno(), line))
以上代码的示例输出为
1->import sqlite3 2->conn = sqlite3.connect('c:/python36/books.db') 3->cursor = conn.cursor() 4->cursor.execute("SELECT * from books;") 5->print(cursor.fetchall())
以下代码打印文件夹中的每个文件名,后跟其中的编号行。在此程序中,使用了 glob() 函数,该函数返回当前路径中文件的列表,可选地使用匹配的通配符。这里 glob(‘*.py’) 将返回当前文件夹中所有扩展名为 .py 的文件的列表。此列表用作 fileinput.input() 函数的 files 参数。
import fileinput, glob, sys for line in fileinput.input(glob.glob("*.py")): if fileinput.isfirstline(): print (fileinput.filename(),'>') sys.stdout.write ("{}.{}".format(fileinput.filelineno(),line))
请注意 isfirstline() 函数的使用。当新文件迭代开始时,此函数返回 true,并首先打印 fileinput.filename() 函数返回的文件名,然后显示带编号的行。例如
1.py > 1.a = 10 2.b = 20 3.print ('addition=',a+b) hello.py > 1.x = 10 2.y = 20 3.z = x+y 4.print ("x+y=",z)
inplace 参数
默认情况下,fileinput.input() 函数的 inplace = False。如果将其设置为 True,则使输入文件可写。
假设有一个名为 'msg.txt' 的文件,其中包含以下文本。
Hello Python. Good morning
以下代码使用 fileinput 模块打开文件并就地修改其内容。
>>> for line in fileinput.input(files='msg.txt',inplace = True): line = line.replace('morning', 'evening') sys.stdout.write(line)
'msg.txt' 将显示所做的更改。