在 Python 中使用 fileinput 模块优雅的读取文件!
此模块,实现了一个辅助类和一些函数用来快速编写访问标准输入或文件列表的循环此模块,实现了一个辅助类和一些函数用来快速访问标准输入或文件列表的循环。
- 其会迭代
sys.argv[1:]
中列出的所有文件的内容,如果列表为空则会使用sys.stdin
替代。 - 文件都默认以文本模式打开,但可以通过调用
input()
或FileInput
时指定mode
形参来重载此行为。 - 如果
sys.stdin
被使用超过一次,则第二次之后的使用将不返回任何行,除非是被交互式的使用或被显式地重置,例如使用sys.stdin.seek(0))
重置。
- [1] 官网地址
- [2] 函数概览
编号 | 模块名称 | 解释说明 |
---|---|---|
1 | fileinput.input() |
返回能够用于 for 循环遍历的对象;创建一个 FileInput 类的实例 |
2 | fileinput.filename() |
返回当前被读取的文件的名称 |
3 | fileinput.fileno() |
返回以整数表示的当前文件“文件描述符” |
4 | fileinput.lineno() |
返回当前已经读取的行的数量或者序号 |
5 | fileinput.filelineno() |
返回当前读取的行的行号 |
6 | fileinput.isfirstline() |
检查当前行是否是文件的第一行;是则返回 True,否则返回 False |
7 | fileinput.isstdin() |
判断最后一行是否从 stdin 中读取;是则返回 True,否则返回 False |
8 | fileinput.nextfile() |
关闭当前正在读取的文件,并开始读取下一个文件 |
9 | fileinput.close() |
关闭 FileInput 对象 |
10 | fileinput.hook_compressed() |
使用 gzip 和 bz2 模块透明地打开 gzip 和 bzip2 压缩的文件 |
11 | fileinput.hook_encoded() |
返回一个通过 open() 打开每个文件的钩子,使用给定的 encoding 和 errors 来读取文件 |
- [3] 典型用法
# 典型用法
import fileinput
for line in fileinput.input():
process(line)
# FileInput实例可以在with语句中被用作上下文管理器
with fileinput.input(files=('spam.txt', 'eggs.txt')) as f:
for line in f:
process(line)
- 这里重点说下,
fileinput.input()
这个函数的参数:
# 函数使用格式
fileinput.input(files=None, inplace=False, backup='', *, mode='r', openhook=None)
# 函数参数列表
files: 多个文件的路径列表
inplace: 用于指定是否将标准输出的结果写回到文件,此参数默认值为 False
backup: 用于指定备份文件的扩展名
bufsize: 指定缓冲区的大小,默认为 0
mode: 打开文件的格式,默认为 r(只读格式)
openhook: 控制文件的打开方式,例如编码格式等
- 这个模块的实际用于在于,可以接受标准输入,即可以通过管道符传入数据给
Python
程序使用。而且,fileinput
的强大之处在可以支持从多个文件同时读取内容。
- [1] 利用 fileinput 读取一个文件所有行
import fileinput
for line in fileinput.input():
filename = fileinput.filename()
lineno = fileinput.lineno()
print(f"{filename} | Line Number: {lineno} | {line}")
# 代码执行输出
>>> python3 test.py data.txt
data.txt | Line Number: 1 |: Python
data.txt | Line Number: 2 |: Java
data.txt | Line Number: 3 |: C/C++
data.txt | Line Number: 4 |: Shell
- [2] 利用 fileinput 读取一个文件所有行
import fileinput
def process(line):
return line.strip() + ' line'
for line in fileinput.input(inplace=True):
print process(line)
# 代码执行输出
>>> python3 test.py 1.txt 2.txt
first line
second line
third line
fourth line
- [3] 利用 fileinput 实现文件内容替换并将原文件作备份
import fileinput
for line in fileinput.input():
print(f"Tag: {line}")
# 代码执行输出
>>> python3 test.py < data.txt > data_out.txt
- [4] 利用 fileinput 做正则替换
import fileinput
import re
for line in fileinput.input():
line = re.sub(r'\* \[(.*)\]\(#(.*)\)', r'<h2 id="\2">\1</h2>', line.rstrip())
print(line)
# 代码执行输出
>>> python3 test.py input.txt
<h2 id="author:Mark Lutz">Learning Python</h2>
- [5] 利用 fileinput 给每行日志前加上接收时的时间戳
from datetime import datetime
import fileinput
for line in fileinput.input():
print(f'[{datetime.now()}] {line}', end='')
# 代码执行输出
>>> tail -f xxx.log | python3 test.py
[2021-05-09 10:41:13.514709] some good thing happend
[2021-05-09 10:41:13.525803] some good thing happend
[2021-05-09 10:41:13.630232] some bad thing happend