Python fileinput 模块多文件迭代与原地修改实战

桃夭
桃夭
发布时间:2026-10-12 | 3人浏览过
原创

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 文件流批量处理与自动化运维的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表