文章目录

  • python之difflib模块
  • 常用方法简介
  • 文件比较
  • 字符串比较
  • filecmp模块比较文件和目录


python之difflib模块

常用方法简介

先用dir查看该模块中有哪些可以的类或者方法

python 比较两个文件夹内容 python对比两个txt文件不同_Diff

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

比较结果:

python 比较两个文件夹内容 python对比两个txt文件不同_文件路径_02

  • 其它例子
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"]