前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >『工作自动化』文件内容差异化对比辅助工具difflib

『工作自动化』文件内容差异化对比辅助工具difflib

作者头像
可以叫我才哥
发布2021-08-05 15:19:21
5430
发布2021-08-05 15:19:21
举报
文章被收录于专栏:可以叫我才哥可以叫我才哥
我们的第78篇原创

作者:才哥


大家好,我是才哥。

最近在工作中遇到一个问题,比对两份文件内容的差异。

然后发现咱们python标准库difflib可以比较不错的实现这一需求,那么今天我们就简单介绍一下这个计算差异的辅助工具

可以先简单看下效果:

对比效果

1. 简介

此模块提供用于比较序列的类和函数。例如,它可被用于比较文件,并可产生多种格式的不同文件差异信息,包括 HTML 和上下文以及统一的 diff 数据。

这里我们只简单介绍它的两个类differhtmldiff,前者用于比较由文本行组成的序列,并产生可供人阅读的差异或增量信息;后者用于创建 HTML 表格(或包含表格的完整 HTML 文件)以并排地逐行显示文本比较,行间与行外的更改将突出显示。

2. Differ类

Differ 增量的每一行均以双字母代码打头:

双字母代码

意义

'- '

行为序列 1 所独有

'+ '

行为序列 2 所独有

' '

行在两序列中相同

'? '

行不存在于任一输入序列

这里的序列是指用于对比的两个文件的内容行,以 '?' 打头的行不属于任何一个序列。

比如,我们用于对比的文件内容如下:

代码语言:javascript
复制
text1 = '''
大家好,这是版本1
在这个版本中,我们可以看到初始功能需求
如果有更多的需求,我们会在后续文档里输出
请持续关注
谢谢
     '''.splitlines(keepends=True)

text2 = '''
大家好,这是版本2
在这个版本中,我们可以看到初始功能需求以及新增需求
如果有更多需求,我们会持续在后续文档里输出
请持续关注我们
谢谢
     '''.splitlines(keepends=True)

注:keepends=True表示含换行符

我们先实例化一个differ对象,任何调用compare方法即可获取差异。

代码语言:javascript
复制
# 实例化一个differ对象
d = difflib.Differ()
# 调用compare方法获取差异
result = list(d.compare(text1, text2))

输出如下:

代码语言:javascript
复制
['  \n',
 '- 大家好,这是版本1\n',
 '?         ^\n',
 '+ 大家好,这是版本2\n',
 '?         ^\n',
 '- 在这个版本中,我们可以看到初始功能需求\n',
 '+ 在这个版本中,我们可以看到初始功能需求以及新增需求\n',
 '?                    ++++++\n',
 '- 如果有更多的需求,我们会在后续文档里输出\n',
 '?      -\n',
 '+ 如果有更多需求,我们会持续在后续文档里输出\n',
 '?            ++\n',
 '- 请持续关注\n',
 '+ 请持续关注我们\n',
 '?      ++\n',
 '  谢谢\n',
 '       ']

为了更方便看到差异,我们可以:

代码语言:javascript
复制
import sys

sys.stdout.writelines(result)

输出如下:

代码语言:javascript
复制
- 大家好,这是版本1
?         ^
+ 大家好,这是版本2
?         ^
- 在这个版本中,我们可以看到初始功能需求
+ 在这个版本中,我们可以看到初始功能需求以及新增需求
?                    ++++++
- 如果有更多的需求,我们会在后续文档里输出
?      -
+ 如果有更多需求,我们会持续在后续文档里输出
?            ++
- 请持续关注
+ 请持续关注我们
?      ++
  谢谢

在输出结果中,^表示有变化的字符位置,-表示被删除的字符位置,+表示新增的字符位置。

大家可能会发现,目前这三个标识符和实际变化的位置对不上。是的,因为目前案例中是中文字符。。。一个中文字符占位相当于2个英文字符占位,所以...有偏差。

我们拿英文字符举例如下:

代码语言:javascript
复制
import difflib
text1 = '''
hello
this is what?
     '''.splitlines(keepends=True)

text2 = '''
Hello,
  that is what?
     '''.splitlines(keepends=True)

d = difflib.Differ()
# 以下也可以让输出格式更方便看差异
print("".join(list(d.compare(text1, text2))))

输出结果如下:

代码语言:javascript
复制
- hello
? ^
+ Hello,
? ^    +
- this is what?
?   ^^
+   that is what?
? ++  ^^

大家发现没有,现在标识符的位置就对了。

3. HtmlDiff类

这个类可用于创建 HTML 表格(或包含表格的完整 HTML 文件)以并排地逐行显示文本比较,行间与行外的更改将突出显示。

我们先实例化一个difflib.HtmlDiff对象,任何调用make_file方法获取结果写入xx.html文件即可获取差异。

代码语言:javascript
复制
# 创建
d = difflib.HtmlDiff()
with open("diff_result.html", 'w') as f:
    f.write(d.make_file(text1, text2))

输出结果为一个html文件,打开可以看到比较清晰的对比:

结果预览

以上就是本次的全部内容了,希望对大家在文件内容对比上有所启发。

关于difflib更多的介绍大家可以参考官方文档:

代码语言:javascript
复制
https://docs.python.org/zh-cn/3/library/difflib.html
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 可以叫我才哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 简介
  • 2. Differ类
  • 3. HtmlDiff类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档