ITPub博客

首页 > 数据库 > 数据库开发技术 > 『工作自动化』文件内容差异化对比辅助工具difflib

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

原创 数据库开发技术 作者:可以叫我才哥 时间:2021-05-18 08:18:00 0 删除 编辑



关注可以叫我才哥,学习分享数据之美

我们的第78篇原创

作者:才哥


☆

大家好,我是才哥。

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

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

可以先简单看下效果:

1. 简介

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

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

2. Differ类

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

双字母代码 意义
'- ' 行为序列 1 所独有
'+ ' 行为序列 2 所独有
' ' 行在两序列中相同
'? ' 行不存在于任一输入序列

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

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

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

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

注:keepends=True表示含换行符

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

# 实例化一个differ对象
d = difflib.Differ()
# 调用compare方法获取差异
result = list(d.compare(text1, text2))

输出如下:

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

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

import sys

sys.stdout.writelines(result)

输出如下:

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

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

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

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

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))))

输出结果如下:

- hello
? ^
+ Hello,
? ^    +
- this is what?
?   ^^
+   that is what?
? ++  ^^

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

3. HtmlDiff类

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

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

# 创建
d = difflib.HtmlDiff()
with open("diff_result.html", 'w') as f:
    f.write(d.make_file(text1, text2))

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

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

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

https://docs.python.org/zh-cn/3/library/difflib.html

-->推荐阅读<--

『小知识』Python自动安装第三方库的小技巧

『小知识』Python输出还可以这么花里胡哨

『数据分析』使用python进行同期群分析

『网络爬虫』自从学会了python,斗图就没怕过谁

『数据分析』pandas计算连续行为天数的几种思路

『福利』14张数据科学速查表+28本Python电子书

『网络爬虫』手把手教你扒一扒贝壳网成交房源数据

『数据分析』浅谈游戏运营中LTV的计算

『数据分析』使用Python计算RFM用户价值模

扫码添加作者好友,一起组队学习

微信号

gdc2918

微信公众号

可以叫我才哥

分享、在看与点赞

爱你一万年~

原文作者:可以叫我才哥;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-03-18

  • 博文量
    161
  • 访问量
    69020