共计 4051 个字符,预计需要花费 11 分钟才能阅读完成。
前情提醒: 测试代码中,右尖括号(>
)表示命令行中输出的命令;独自一行并以井字符(#
)结尾的为输入内容;库的导入仅在本文的第一个测试代码中展示,其余代码块均省略库的导入代码。
- 零碎类型:
Windows 10
- python 版本:
Python 3.9.0
filecmp
模块能够用于文件与文件之间或目录与目录之间的比拟。并且能够通过设置参数来选取多种不同用时和不同准确性的计划。
filecmp
模块在进行文件或目录比照时,最终仅能返回是否相等这一后果。某些场景须要更加具体的后果阐明,能够应用 difflib
规范库。
快捷函数
filecmp.cmp(f1, f2, shallow=True)
参数:
f1, f2: 要进行比拟的两个文件
shallow: 关键字参数, 参数值为布尔值, 默认为 True;
如果为 True, 则判断两文件须要具备雷同的 os.stat() 签名才会认为是相等的;
如果为 False, 则比拟两文件的内容;
返回值:
布尔值, 两个文件是否相等
比拟 f1
和 f2
的文件,如果它们仿佛相等则返回 True
,否则返回 False
。在官网文档中用上了 ‘ 仿佛 ’ 一词,这让人感觉有什么隐秘的信息文档上没有表达出来。
import filecmp
import os
'''本次测试代码中存在 4 个待比照文件, 其中 文件 1 与 文件 2 内容不同, 文件 3 与 文件 4 内容雷同'''
print(os.stat('文件 1'))
print(os.stat('文件 2'))
print(filecmp.cmp('文件 1', '文件 2', shallow=True))
print(filecmp.cmp('文件 1', '文件 2', shallow=False))
# os.stat_result(st_mode=33206, st_ino=1407374883609775, st_dev=3098197482, st_nlink=1, st_uid=0, st_gid=0, st_size=4, st_atime=1611109066, st_mtime=1611109066, st_ctime=1611043715)
# os.stat_result(st_mode=33206, st_ino=1688849860320432, st_dev=3098197482, st_nlink=1, st_uid=0, st_gid=0, st_size=4, st_atime=1611045689, st_mtime=1611045689, st_ctime=1611043722)
# True
# True
当比拟内容雷同的 文件 1
与 文件 2
时,参数 shallow
无论设置为 True
还是 False
后果都是 True
。依照文档所述,文件 1
和 文件 2
的 os.stat()
是不雷同的,当参数 shallow
设置为 True
时,依据两个文件的 os.stat()
最终应该失去 False
。为什么理论运行和文档形容不同呢?
查阅一些材料后,找到了一个比拟正当的解释,当参数 shallow
设置为 True
,那么 os.stat()
雷同的会间接被视为相等,当两个文件的 os.stat()
不同时,依旧会比照文件中的内容。
另外,此函数会缓存比拟后果,在下次比拟时间接返回缓存后果。如果文件的 os.stat()
变动了,也就是文件被批改了,缓存主动生效。缓存也能用下文中的 filecmp.clear_cache()
函数革除。
filecmp.cmpfiles(dir1, dir2, common, shallow=True)
参数:
dir1, dir2: 目录
common: 须要比照的文件名列表
shallow: 关键字参数, 参数值为布尔值, 默认为 True;
如果为 True, 则判断两文件须要具备雷同的 os.stat() 签名才会认为是相等的;
如果为 False, 则比拟两文件的内容;
返回值:
元组, 蕴含三个类型为列表的元素.
比拟两个目录下的指定文件,返回比照后果,返回值是蕴含三个类型为列表的元素的元组。
'''
文件目录如下, 其中, 两个目录内的 文件 a 内容雷同, 文件 c 内容不同
- 目录 1
- 文件 a
- 目录 b
- 文件 c
- 文件 d
- 目录 2
- 文件 a
- 目录 b
- 文件 c
'''''' 比照两目录下的文件 '''print(filecmp.cmpfiles(' 目录 1',' 目录 2', [' 文件 a',' 目录 b / 文件 c',' 文件 d']))
# (['文件 a'], ['目录 b / 文件 c'], ['文件 d'])
参数 common
列举要比照的文件名,别离比照两个目录下的同名文件,如果两个文件雷同,则退出返回值的第一个元素内; 如果两个文件内容不同,则退出返回值的第二个元素内; 如果文件无权限读取或者文件在任一目录内缺失,则退出返回值的第三个元素内;
参数 shallow
与上文中 filecmp.cmp()
函数意义雷同。
filecmp.clear_cache()
革除 filecmp
缓存。个别状况下,文件批改后,文件的 os.stat()
天然会扭转,缓存也会主动生效。然而如果文件被过快的批改,以至于超过底层文件系统记录批改工夫的精度时,那么尔后的文件比照将可能会呈现问题,此函数就是为了解决这个问题。
然而,这种文件过快的批改不晓得怎么测试进去? 大家有晓得的吗?
dircmp 类
class filecmp.dircmp(a, b, ignore=None, hide=None)
参数:
a, b: 目录
ignore: 关键字参数, 须要疏忽的文件名列表, 默认为 filecmp.DEFAULT_IGNORES
hide: 关键字参数, 须要暗藏的文件名列表, 默认为 [os.curdir, os.pardir]
创立一个用于比拟两个目录的目录比拟对象。参数 ignore
可疏忽指定的文件名,hide
可暗藏指定的文件名。
print(filecmp.DEFAULT_IGNORES)
# ['RCS', 'CVS', 'tags', '.git', '.hg', '.bzr', '_darcs', '__pycache__']
print(os.curdir)
# .
print(os.pardir)
# ..
dircmp
类中有许多属性,这里应用测试代码间接展现:
dircmp_test = filecmp.dircmp('目录 1', '目录 2')
'''第一个 (绝对右边) 参数, 也是第一个目录的名称'''
print(dircmp_test.left)
# 目录 1
'''第二个 (绝对左边) 参数, 也是第二个目录的名称'''
print(dircmp_test.right)
# 目录 2
'''经参数 hide 与参数 ignore 过滤后, 第一个目录内的所有文件与子目录'''
print(dircmp_test.left_list)
# ['文件 a', '文件 d', '目录 b']
'''经参数 hide 与参数 ignore 过滤后, 第二个目录内的所有文件与子目录'''
print(dircmp_test.right_list)
# ['文件 a', '目录 b']
'''同时存在两个目录下的文件与子目录'''
print(dircmp_test.common)
# ['文件 a', '目录 b']
'''仅存在第一个目录下的文件与子目录'''
print(dircmp_test.left_only)
# ['文件 d']
'''仅存在第二个目录下的文件与子目录'''
print(dircmp_test.right_only)
# []
'''同时存在两个目录下的子目录'''
print(dircmp_test.common_dirs)
# ['目录 b']
'''将 common_dirs 属性值映射为 dircmp 对象的字典'''
print(dircmp_test.subdirs)
# {'目录 b': <filecmp.dircmp object at 0x000002A9A1374F70>}
'''同时存在两个目录下的文件'''
print(dircmp_test.common_files)
# ['文件 a']
'''在两个目录中类型不同的名字,或者那些 os.stat() 报告谬误的名字'''
print(dircmp_test.common_funny)
# []
'''在两个目录下, 应用类的比拟操作符雷同的文件'''
print(dircmp_test.same_files)
# ['文件 a']
'''在两个目录下, 应用类的比拟操作符不同的文件'''
print(dircmp_test.diff_files)
# []
'''无奈比拟的文件'''
print(dircmp_test.funny_files)
# []
dircmp
类也提供了一些用于打印信息的办法,同样,间接在测试用例中展现:
'''将 a 与 b 之间的比拟打印'''
dircmp_test.report()
# diff 目录 1 目录 2
# Only in 目录 1 : ['文件 d']
# Identical files : ['文件 a']
# Common subdirectories : ['目录 b']
'''打印 a 与 b 及独特间接子目录的比拟后果'''
dircmp_test.report_partial_closure()
# diff 目录 1 目录 2
# Only in 目录 1 : ['文件 d']
# Identical files : ['文件 a']
# Common subdirectories : ['目录 b']
#
# diff 目录 1\ 目录 b 目录 2\ 目录 b
# Differing files : ['文件 c']
'''打印 a 与 b 及独特子目录比拟后果(递归地)'''
dircmp_test.report_full_closure()
# diff 目录 1 目录 2
# Only in 目录 1 : ['文件 d']
# Identical files : ['文件 a']
# Common subdirectories : ['目录 b']
#
# diff 目录 1\ 目录 b 目录 2\ 目录 b
# Differing files : ['文件 c']
公众号 :「python 杂货铺」,专一于 python 语言及其相干常识。挖掘更多原创文章,期待您的关注。
参考资料
官网文档
源代码
python – filecmp.cmp()疏忽不同的 os.stat()签名?