Python3 filecmp模块测试比较文件原理解析


Posted in Python onMarch 23, 2020

1.filecmp比较文件

filecmp模块提供了一些函数和一个类来比较文件系统上的文件和目录。

1.1 示例数据

使用下面代码创建一组测试文件。

import os
def mkfile(filename, body=None):
  with open(filename, 'w') as f:
    f.write(body or filename)
  return
 
def make_example_dir(top):
  if not os.path.exists(top):
    os.mkdir(top)
  curdir = os.getcwd()
  os.chdir(top)
  os.mkdir('dir1')
  os.mkdir('dir2')
  mkfile('dir1/file_only_in_dir1')
  mkfile('dir2/file_only_in_dir2')
  os.mkdir('dir1/dir_only_in_dir1')
  os.mkdir('dir2/dir_only_in_dir2')
  os.mkdir('dir1/common_dir')
  os.mkdir('dir2/common_dir')
  mkfile('dir1/common_file', 'this file is the same')
  os.link('dir1/common_file', 'dir2/common_file')
  mkfile('dir1/contents_differ')
  mkfile('dir2/contents_differ')
  # Update the access and modification times so most of the stat
  # results will match.
  st = os.stat('dir1/contents_differ')
  os.utime('dir2/contents_differ', (st.st_atime, st.st_mtime))
  mkfile('dir1/file_in_dir1', 'This is a file in dir1')
  os.mkdir('dir2/file_in_dir1')
  os.chdir(curdir)
  return
 
if __name__ == '__main__':
  os.chdir(os.path.dirname(__file__) or os.getcwd())
  make_example_dir('example')
  make_example_dir('example/dir1/common_dir')
  make_example_dir('example/dir2/common_dir')

运行这个脚本会在axample目录下生成一个文件树。

Python3 filecmp模块测试比较文件原理解析

common_dir目录下也有同样的目录结构,以提供有意思的递归比较选择。

1.2 比较文件

cmp()用于比较文件系统上的两个文件。

import filecmp
print('common_file  :', end=' ')
print(filecmp.cmp('example/dir1/common_file',
         'example/dir2/common_file',
         shallow=True),
   end=' ')
print(filecmp.cmp('example/dir1/common_file',
         'example/dir2/common_file',
         shallow=False))
print('contents_differ:', end=' ')
print(filecmp.cmp('example/dir1/contents_differ',
         'example/dir2/contents_differ',
         shallow=True),
   end=' ')
print(filecmp.cmp('example/dir1/contents_differ',
         'example/dir2/contents_differ',
         shallow=False))
print('identical   :', end=' ')
print(filecmp.cmp('example/dir1/file_only_in_dir1',
         'example/dir1/file_only_in_dir1',
         shallow=True),
   end=' ')
print(filecmp.cmp('example/dir1/file_only_in_dir1',
         'example/dir1/file_only_in_dir1',
         shallow=False))

shallo参数告诉cmp()除了文件的元数据外,是否还要查看文件的内容。默认情况下,会使用由os.stat()得到的信息来完成一个浅比较。如果结果是一样的,则认为文件相同。因此,对于同时创建的相同大小的文件,即使他们的内容不同,也会报告为是相同的文件。当shallow为False时,则要比较文件的内容。

Python3 filecmp模块测试比较文件原理解析

如果非递归的比较两个目录中的一组文件,则可以使用cmpfiles()。参数是目录名和两个位置上要检查的我就爱你列表。传入的公共文件列表应当只包含文件名(目录会导致匹配不成功),而且这些文件在两个位置上都应当出现。下一个例子显示了构造公共列表的一种简单方法。与cmp()一样,这个比较也有一个shallow标志。

import filecmp
import os
# Determine the items that exist in both directories
d1_contents = set(os.listdir('example/dir1'))
d2_contents = set(os.listdir('example/dir2'))
common = list(d1_contents & d2_contents)
common_files = [
  f
  for f in common
  if os.path.isfile(os.path.join('example/dir1', f))
]
print('Common files:', common_files)
# Compare the directories
match, mismatch, errors = filecmp.cmpfiles(
  'example/dir1',
  'example/dir2',
  common_files,
)
print('Match    :', match)
print('Mismatch  :', mismatch)
print('Errors   :', errors)

cmpfiles()返回3个文件名列表,分别包含匹配的文件、不匹配的文件和不能比较的文件(由于权限问题或出于其他原因)。

Python3 filecmp模块测试比较文件原理解析

1.3 比较目录

前面介绍的函数适合完成相对简单的比较。对于大目录树的递归比较或者更完整的分析,dircmp类很更有用。在最简单的用例中,report()会打印比较两个目录的报告。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
dc.report()

输出是一个纯文本报告,显示的结果只包括给定目录的内容,而不会递归比较其子目录。在这里,认为文件not_the_same是相同的,因为这里没有比较内容。无法让dircmp像cmp()那样比较文件的内容。

Python3 filecmp模块测试比较文件原理解析

为了更多的细节,也为了完成一个递归比较,可以使用report_full_closure()。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
dc.report_full_closure()

输出将包括所有同级子目录的比较。

Python3 filecmp模块测试比较文件原理解析

1.4 在程序中使用差异

除了生成打印报告,dircmp还能计算文件列表,可以在程序中直接使用。以下各个属性只在请求时才计算,所以对于未用的数据,创建dircmp实例不会带来开销。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Left:')
pprint.pprint(dc.left_list)
print('\nRight:')
pprint.pprint(dc.right_list)

所比较目录中包含的文件和子目录分别列在left_list和right_list中。

Python3 filecmp模块测试比较文件原理解析

可以向构造函数传入一个要忽略的名字列表(该列表中指定的名字将被忽略)来对输入进行过滤。默认的,RCS、CVS和tags等名字会被忽略。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2',
          ignore=['common_file'])
print('Left:')
pprint.pprint(dc.left_list)
print('\nRight:')
pprint.pprint(dc.right_list)

在这里,将common_file从要比较的文件列表中去除。

Python3 filecmp模块测试比较文件原理解析

两个输入目录中共有的文件名会保存在common内,各目录独有的文件会列在left_only和right_only中。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Common:')
pprint.pprint(dc.common)
print('\nLeft:')
pprint.pprint(dc.left_only)
print('\nRight:')
pprint.pprint(dc.right_only)

"左"目录是dircmp()的第一个参数,"右"目录是第二个参数。

Python3 filecmp模块测试比较文件原理解析

公共成员可以被进一步分解为文件、目录和“有趣”元素(两个目录中类型不同的内容,或者os.stat()指出的有错误的地方)。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Common:')
pprint.pprint(dc.common)
print('\nDirectories:')
pprint.pprint(dc.common_dirs)
print('\nFiles:')
pprint.pprint(dc.common_files)
print('\nFunny:')
pprint.pprint(dc.common_funny)

在示例数据中,file_in_dir1元素在一个目录中是一个文件,而在另一个目录中是一个子目录,所以它会出现在“有趣”列表中。

Python3 filecmp模块测试比较文件原理解析

文件之间的差别也可以做类似的划分。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Same   :', dc.same_files)
print('Different :', dc.diff_files)
print('Funny   :', dc.funny_files)

文件not_the_same通过os.stat()比较,并且不检查内容,所以它包含在same_files列表中。

Python3 filecmp模块测试比较文件原理解析

最后一点,子目录也会被保存,以便容易地完成递归比较。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Subdirectories:')
print(dc.subdirs)

属性subdirs是一个字典,它将目录名映射到新的dircmp对象。

Python3 filecmp模块测试比较文件原理解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python win32com 操作Exce的l简单方法(必看)
May 25 Python
用python处理图片实现图像中的像素访问
May 04 Python
python中的数据结构比较
May 13 Python
python输出电脑上所有的串口名的方法
Jul 02 Python
Django 模型类(models.py)的定义详解
Jul 19 Python
numpy np.newaxis 的实用分享
Nov 30 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
python 实现PIL模块在图片画线写字
May 16 Python
python中可以声明变量类型吗
Jun 18 Python
Pythonic版二分查找实现过程原理解析
Aug 11 Python
Python filter()及reduce()函数使用方法解析
Sep 05 Python
深度学习tensorflow基础mnist
Apr 14 Python
python实现遍历文件夹图片并重命名
Mar 23 #Python
Python3 mmap内存映射文件示例解析
Mar 23 #Python
Python3 io文本及原始流I/O工具用法详解
Mar 23 #Python
python实现横向拼接图片
Mar 23 #Python
Python操作Excel工作簿的示例代码(\*.xlsx)
Mar 23 #Python
python实现拼接图片
Mar 23 #Python
python使用PIL剪切和拼接图片
Mar 23 #Python
You might like
php中的路径问题与set_include_path使用介绍
2014/02/11 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
Mootools 1.2教程 输入过滤第一部分(数字)
2009/09/15 Javascript
jquery组件使用中遇到的问题整理及解决
2014/02/21 Javascript
JS案例分享之金额小写转大写
2014/05/15 Javascript
JS应用正则表达式转换大小写示例
2014/09/18 Javascript
jQuery中用dom操作替代正则表达式
2014/12/29 Javascript
BootStrap下jQuery自动完成的样式调整
2016/05/30 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
使用cookie绕过验证码登录的实现代码
2017/10/12 Javascript
JS实现把一个页面层数据传递到另一个页面的两种方式
2018/08/13 Javascript
angular6的table组件开发的实现示例
2018/12/26 Javascript
详解Puppeteer前端自动化测试实践
2019/02/21 Javascript
Vue中props的详解
2019/05/16 Javascript
vue-cli3中vue.config.js配置教程详解
2019/05/29 Javascript
关于layui导航栏不展示下拉列表的解决方法
2019/09/25 Javascript
浅谈Three.js截图并下载的大坑
2019/11/01 Javascript
jQuery实现简单评论区功能
2020/10/26 jQuery
Python and、or以及and-or语法总结
2015/04/14 Python
对于Python装饰器使用的一些建议
2015/06/03 Python
pygame游戏之旅 如何制作游戏障碍
2018/11/20 Python
Python判断对象是否相等及eq函数的讲解
2019/02/25 Python
python set集合使用方法解析
2019/11/05 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
通过一张图教会你CSS3倒影的实现
2017/09/26 HTML / CSS
英国领先的家庭时尚品牌:Peacocks
2018/01/11 全球购物
新西兰购物网站:TheMarket NZ
2020/09/19 全球购物
同步和异步有何异同,在什么情况下分别使用他们?
2012/12/28 面试题
思想品德自我鉴定
2013/10/12 职场文书
户外用品商店创业计划书
2014/01/29 职场文书
求职信的七个关键技巧
2014/02/05 职场文书
农村党支部书记司法四风问题对照检查材料
2014/09/26 职场文书
投资意向协议书
2015/01/29 职场文书
2016毕业实习单位评语大全
2015/12/01 职场文书
九不准学习心得体会
2016/01/23 职场文书
一起来学习Python的元组和列表
2022/03/13 Python