Python fileinput 模块多文件迭代与原地修改实战
fileinput 模块专为迭代处理一个或多个文本文件设计,采用逐行生成的惰性读取方式,在批量处理大文件时可显著降低内存占用。相比传统的 open() 结合循环,它原生支持原地修改、自动备份、跨文件序号追踪及自定义读取钩子。通过合理配置参数与方法,可快速实现日志清洗、代码批量检索与格式标准化等任务。
核心特性与适用场景
许多开发者习惯使用 open() 手动管理文件句柄,但在需要连续读取多个文件或频繁切换读写源时,代码会变得冗长且易出错。fileinput 模块作为 open() 的高级封装,内部维护了一个文件列表队列与当前游标状态。其 input() 函数返回一个迭代器对象,每次仅向内存加载一行数据,非常适合处理 GB 级别的日志或配置文件。此外,该模块无缝对接命令行参数解析与标准输入流,可直接用于 Shell 管道数据清洗。
常用方法与参数配置
调用模块前需明确核心参数与状态查询函数。这些组件共同构成了文件的遍历控制与元数据获取体系:
fileinput.input(files, inplace, backup):初始化读取队列。files接收文件路径列表(默认为sys.argv[1:]或标准输入);inplace决定是否重定向标准输出回原文件;backup指定备份后缀(如.bak)。fileinput.filename():返回当前正在读取的文件绝对路径。fileinput.lineno():返回累计读取的总行数。fileinput.filelineno():返回当前文件内部的相对行号。fileinput.isfirstline():布尔值,判断当前是否为对应文件的起始行。fileinput.close():释放底层资源并关闭所有已打开的文件句柄。
第1步:基础迭代读取单个或多个文件
目的:在不将整个文件载入内存的前提下,顺序遍历指定目录下的多个文本文件,并获取每行内容与位置信息。
操作入口:import fileinput 配合 glob 库筛选目标文件。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import fileinput
from glob import glob
# 读取当前目录下所有 .txt 文件,按顺序逐行打印
with fileinput.input(files=glob("*.txt")) as f:
for line in f:
# 动态获取当前文件名、文件内行号与全局累计行号
fname = fileinput.filename()
cur_lineno = fileinput.filelineno()
total_lineno = fileinput.lineno()
print(f"{fname} -> {line.strip()} | 文件内第{cur_lineno}行 | 累计第{total_lineno}行")
关键参数:传入列表到 files 参数;上下文管理器 with 确保循环结束后自动调用 close()。
完成状态:控制台按输入顺序依次输出每个文件的原始行内容,末尾无多余空白,说明迭代正常终止且资源已回收。
第2步:原地替换内容并生成备份
目的:直接修改原有文件内容(例如过滤注释、替换关键字),同时保留原始数据以防误操作覆盖。
风险提醒:开启原地修改后,程序内的 print() 语句将不再输出至终端,而是写入当前处理的文件中。建议在执行前手动复制一份测试集。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import fileinput
from glob import glob
# 开启 inplace 模式并设定备份扩展名
with fileinput.input(files=glob("*.py"), inplace=True, backup=".bak") as f:
for line in f:
# 过滤掉包含特定标记的行,保留其余内容自动写回原文件
if "# skip" not in line:
print(line, end="") # end="" 防止追加额外换行符
print(f"{fileinput.filename()} -> 剩余第{fileinput.filelineno()}行 | 已处理{fileinput.lineno()}行")
操作说明:当 inplace=True 时,文件会被临时重命名(后缀为 backup 的值),新文件创建后写入流会指向它。处理完毕后旧文件被删除,新文件改回原名。
完成状态:原目录生成带指定后缀的备份文件(如 .bak),主文件内容已被过滤替换,且未产生乱码或意外截断。
第3步:利用钩子统一编码与解压
目的:解决跨平台文本处理中的编码冲突问题,并实现对压缩包内容的透明读取。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import fileinput
from glob import glob
# 使用内置编码钩子强制指定 UTF-8,避免 Windows/Linux 间读取报错
with fileinput.input(files=glob("*.*"), openhook=fileinput.hook_encoded("utf-8")) as f:
for line in f:
print(line.upper().strip())
参数解析:
openhook=fileinput.hook_compressed:自动识别.gz或.bz2扩展名并解压,非压缩文件则降级为普通打开。openhook=fileinput.hook_encoded(encoding, errors):拦截所有open()调用,统一注入编码与错误处理策略(如"surrogateescape")。
完成状态:无论源文件是纯文本、Unicode 变体还是压缩归档,均能一次性完整解析并输出预处理结果,无需手动编写 try-except 或导入 gzip 模块。
简要总结
fileinput 模块以极低的认知成本接管了多文件流式读取、原位编辑与编码管理的繁琐工作。通过组合 inplace 安全机制与 openhook 扩展点,开发者可构建高鲁棒性的数据清洗流水线。掌握各状态函数的联动逻辑后,日常批处理任务的代码量可缩减一半以上。以上就是 Python fileinput 模块应用详解的详细内容,更多关于 Python 文件流批量处理与自动化运维的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









