文章目录
- python之difflib模块
- 常用方法简介
- 文件比较
- 字符串比较
- filecmp模块比较文件和目录
python之difflib模块
常用方法简介
先用dir查看该模块中有哪些可以的类或者方法
difflib模块最常用的2个类就是Differ和HtmlDiff
Differ用来比较文本内容,比较结果用一些特殊的符号表示:
'-' 第1个序列中出现
'+ ' 第2个序列中出现
' ' 两行相同
'? ' 增量差异
'^' 字符差异
HtmlDiff类用来将比较结果存到html文件中,一般用法就是实例化HtmlDiff类之后,调用其make_file方法对两个文件进行比较,之后调用open函数将比较结果写入到结果文件中。
文件比较
通过open()函数直接把给定的文件路径,所有内容读取出来,保存到列表中,然后传递给difflib中的make_file进行比较即可
注意:读的时候使用二进制rb模式,可以防止各种乱码的问题,读完之后通过decode转换为utf-8再进行比较
import difflib
class DiffFile:
"""文件比较类"""
@classmethod
def _read_file(cls, file):
"""
读取文件内容,以列表形式返回
:param file: 文件路径
:return:
"""
try:
with open(file, "rb") as fp:
# 二进制方式读取文件内容,并转换为str类型
lines = fp.read().decode('utf-8')
# 按行进行分割
text = lines.splitlines()
# print text
return text
except Exception as e:
print("ERROR: %s" % str(e))
@classmethod
def compare_file(cls, file1, file2, out_file):
"""
比较文件,生成html格式
:param file1: 第1个文件路径
:param file2: 第2个文件路径
:param out_file: 比较结果文件路径
:return:
"""
file1_content = cls._read_file(file1)
file2_content = cls._read_file(file2)
compare = difflib.HtmlDiff()
compare_result = compare.make_file(file1_content, file2_content)
with open(out_file, 'w') as fp:
fp.writelines(compare_result)
字符串比较
可以直接输出,也可以保存到html文件中
@classmethod
def compare_text(cls, src_text, target_text):
"""
比较给定的2个字符串
:param src_text:
:param target_text:
:return:
"""
d = difflib.Differ()
return "".join(list(d.compare(src_text, target_text)))
@classmethod
def compare_text_to_file(cls, src_text, target_text, out_file):
"""
比较给定的2个字符串,生成html格式
:param src_text:
:param target_text:
:param out_file:
:return:
"""
compare = difflib.HtmlDiff()
compare_result = compare.make_file(src_text, target_text)
with open(out_file, 'w') as fp:
fp.writelines(compare_result)
- 完整代码
# -*- encoding: utf-8 -*-
"""
@File : diff.py
@Time :
@Author :
"""
import difflib
class DiffFile:
"""文件比较类"""
@classmethod
def _read_file(cls, file):
"""
读取文件内容,以列表形式返回
:param file: 文件路径
:return:
"""
try:
with open(file, "rb") as fp:
# 二进制方式读取文件内容,并转换为str类型
lines = fp.read().decode('utf-8')
# 按行进行分割
text = lines.splitlines()
# print text
return text
except Exception as e:
print("ERROR: %s" % str(e))
@classmethod
def compare_file(cls, file1, file2, out_file):
"""
比较文件,生成html格式
:param file1: 第1个文件路径
:param file2: 第2个文件路径
:param out_file: 比较结果文件路径
:return:
"""
file1_content = cls._read_file(file1)
file2_content = cls._read_file(file2)
compare = difflib.HtmlDiff()
compare_result = compare.make_file(file1_content, file2_content)
with open(out_file, 'w') as fp:
fp.writelines(compare_result)
@classmethod
def compare_text(cls, src_text, target_text):
"""
比较给定的2个字符串
:param src_text:
:param target_text:
:return:
"""
d = difflib.Differ()
return "".join(list(d.compare(src_text, target_text)))
@classmethod
def compare_text_to_file(cls, src_text, target_text, out_file):
"""
比较给定的2个字符串,生成html格式
:param src_text:
:param target_text:
:param out_file:
:return:
"""
compare = difflib.HtmlDiff()
compare_result = compare.make_file(src_text, target_text)
with open(out_file, 'w') as fp:
fp.writelines(compare_result)
if __name__ == '__main__':
DiffFile.compare_file('Demo.py', "Demo2.py", 'diff.html')
text1 = ''' 1. Beautiful is better than ugly.
2. Explicit is better than implicit.
3. Simple is better than complex.
4. Complex is better than complicated.
'''.splitlines(keepends=True)
text2 = ''' 1. Beautiful is better than ugly.
3. Simple is better than complex.
4. Complicated is better than complex.
5. Flat is better than nested.
'''.splitlines(keepends=True)
print(DiffFile.compare_text_to_file(text1, text2, 'text_diff.html'))
比较结果:
- 其它例子
import difflib
a = open('./1.txt', 'U').readlines()
b = open('./2.txt', 'U').readlines()
diff = difflib.ndiff(a, b)
print(diff)
for i in diff:
print(i)
# if i.startswith('+'):
# print(i)
#or
print(set(b)-set(a))
filecmp模块比较文件和目录
filecmp是python内置的一个模块,用于比较文件及文件夹的内容。
filecmp有两个主要的方法:
filecmp.cmp(f1, f2, [shallow])
filecmp.cmpfiles(a, b, common, [shallow])
filecmp.cmp(f1, f2, [shallow]),用于比较两个文件。f1、f2是文件名称,shallow为可选参数,指定比较文件时是否需要考虑文件本身的属性,默认是True。
import filecmp
"""
说明:text.txt和text1.txt内容不相同,text.txt和text2.txt内容相同。
"""
res1 = filecmp.cmp("text.txt", "text1.txt", shallow=True)
print("text.txt与text1.txt的比较结果是:{}".format(res1))
res2 = filecmp.cmp("text.txt", "text2.txt", shallow=True)
print("text.txt与text2.txt的比较结果是:{}".format(res2))
结果
text.txt与text1.txt的比较结果是:False
text.txt与text2.txt的比较结果是:True
filecmp.cmpfiles(a, b, common, [shallow]),用于比较两个目录。a, b为目录路径,common为比较文件列表,shallow为可选参数,如果其值为True,则仅比较文件的元数据,即文件的os.stat()签名(如大小,修改日期等),如果它们具有相同的签名,则无论文件内容如何,文件都被视为相等。如果为False,则比较文件的内容。此参数的默认值为True。
import filecmp
"""
说明:
dir1中有三个文件,"text.txt", "text1.txt", "text2.txt"
dir2中有两个文件,"text.txt", "text1.txt"
两个文件夹中的"text.txt"文件一样,"text1.txt"文件不一样
"""
dir1 = r'D:\PythonWorkFolder\wsw\test\folder'
dir2 = r'D:\PythonWorkFolder\wsw\test\folder1'
common_list = ["text.txt", "text1.txt", "text2.txt"]
match, mismatch, errors = filecmp.cmpfiles(dir1, dir2, common_list, shallow=True)
print("比较的结果中,匹配的是:\n{}\n不匹配的是:\n{}\n错误的是:\n{}\n".format(match, mismatch, errors))
此函数会返回三个列表,分别存放匹配文件名称、不匹配文件名称、错误文件名称:
比较的结果中,匹配的是:
["text.txt"]
不匹配的是:
["text1.txt"]
错误的是:
["text2.txt"]