Python对比两个文本文件差异:difflib生成清晰对比结果
用Python标准库difflib对比两个文本文件,输出逐行差异、新增行、删除行,支持生成HTML对比报告,完整代码。
场景痛点
两个版本的配置文件、代码文件、合同文本,想知道到底改了哪几行。肉眼对着看很容易漏掉小字改动。用Python的difflib库,把两个文件读入行列表,自动输出新增、删除、修改的行,还能生成HTML报告方便分享给同事。
用到的库
difflib # 标准库,序列差异对比
pathlib # 标准库
完整代码
import difflib
from pathlib import Path
def read_lines(file_path: str) -> list:
"""读取文本文件所有行,自动处理编码"""
p = Path(file_path)
# 尝试UTF-8,失败则用GBK
for encoding in ['utf-8', 'gbk', 'utf-8-sig']:
try:
return p.read_text(encoding=encoding).splitlines()
except UnicodeDecodeError:
continue
raise ValueError(f"无法识别文件编码: {file_path}")
def diff_text_files(file_a: str, file_b: str, html_output: str = None) -> str:
"""
对比两个文本文件,输出统一格式的差异文本
:param file_a: 旧版本文件
:param file_b: 新版本文件
:param html_output: 如果指定,同时生成HTML对比报告
:return: 差异文本
"""
lines_a = read_lines(file_a)
lines_b = read_lines(file_b)
# ndiff 生成逐行对比,以 '-' '+' '?' ' ' 开头
diff = difflib.ndiff(lines_a, lines_b)
diff_text = '\n'.join(diff)
# 统计
added = sum(1 for l in diff if l.startswith('+ '))
removed = sum(1 for l in diff if l.startswith('- '))
print(f"对比 {Path(file_a).name} vs {Path(file_b).name}")
print(f" 新增行: {added}")
print(f" 删除行: {removed}")
# 生成HTML报告
if html_output:
html = difflib.HtmlDiff().make_file(lines_a, lines_b,
fromdesc=file_a, todesc=file_b)
Path(html_output).write_text(html, encoding='utf-8')
print(f" HTML报告已生成: {html_output}")
return diff_text
if __name__ == "__main__":
diff_text_files(
file_a="./config_v1.txt",
file_b="./config_v2.txt",
html_output="./diff_report.html"
)
代码讲解
read_lines:依次尝试UTF-8、GBK、带BOM的UTF-8三种编码读取文件。中文Windows下导出的文本经常是GBK编码,不处理会乱码。difflib.ndiff(lines_a, lines_b):逐行对比两个字符串列表,返回的每一行前缀有四种含义:-表示旧版本独有(删除),+表示新版本独有(新增),?表示行内差异提示,表示两边相同。difflib.HtmlDiff().make_file(...):生成带高亮的HTML对比报告,新增行绿色、删除行红色,浏览器打开就能看。- 统计逻辑:遍历ndiff结果,按前缀计数,快速得出新增和删除行数。
运行结果
终端打印新增和删除行数统计。如果指定了html_output,会生成diff_report.html,浏览器打开后左右并排显示两个文件,差异行用颜色标注。
注意事项
- 大文件(几十万行)用ndiff会比较慢,因为它是O(n²)算法。超长文件建议先截取相关片段再对比。
- 二进制文件(图片、Excel、PDF)不能用这个方法对比,会输出乱码。二进制对比请直接比文件MD5。
- HTML报告是单文件内联样式,不依赖外部资源,可以直接发邮件或放到内网共享。

更新时间:2026-09-14 21:23:18