fileinput适合只读逐行多文件合并处理,但不支持写入、不保留上下文、遇编码错误直接崩溃;默认用系统编码导致unicodedecodeerror,需用hook_encoded或chardet探测编码;filename()和lineno()返回累计行号而非当前文件行号;inplace=true依赖临时文件且有风险。

直接说结论:fileinput 适合“只读+逐行+多文件合并处理”的简单场景,但默认不支持写入、不保留文件上下文、遇到编码错误会直接崩溃——别把它当万能文件处理器用。
为什么 fileinput.input() 一运行就报 UnicodeDecodeError
它默认用系统编码(比如 Windows 的 cp1252)打开所有文件,只要某个文件含 UTF-8 BOM 或中文但没声明编码,就会炸。不是 bug,是设计如此。
- 加参数
openhook=fileinput.hook_encoded("utf-8")强制统一解码,但对混合编码文件仍无效 - 更稳的做法是先用
chardet探测单个文件编码,再用原生open()处理——fileinput不提供探测能力 - 若文件来自用户上传或日志归档,建议绕过
fileinput,改用pathlib.Path().glob()+ 手动open(encoding=...)
fileinput.filename() 和 fileinput.lineno() 的真实行为
这两个函数返回的不是“当前文件第几行”,而是“从第一个文件开始累计的总行号”和“当前正在读的文件名”。一旦换文件,filename() 立刻变,但 lineno() 不重置。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 想按文件统计行数?得自己记:
if fileinput.isfirstline(): current_file_line = 0,然后每行current_file_line += 1 -
fileinput.isstdin()只在读取管道输入(如cat a.txt b.txt | python script.py)时为True,别指望它识别重定向文件 - 调用
fileinput.nextfile()可主动切到下一个文件,但会跳过当前文件剩余行——这动作不可逆
想边读边改文件?fileinput 的 inplace=True 是把双刃剑
它实际是把原文件重命名为 xxx.bak,再新建同名文件写入——看着像原地修改,实则依赖临时文件和原子重命名,且失败时可能留烂摊子。
- 必须确保磁盘有足够空间存备份,否则写一半失败,原文件已消失
- Windows 下对正在被其他进程占用的文件会直接报
PermissionError,Linux 也可能因 NFS 挂载问题失败 - 若需正则替换,别写
re.sub(..., line)后直接print();记得末尾加line.rstrip('\n') + '\n',否则空行变双换行
真正麻烦的从来不是怎么遍历多文件,而是你得提前知道:哪些文件能安全读、编码是否一致、是否允许临时备份、出错时能否接受部分失败。这些判断 fileinput 一概不管。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










