filecmp.cmp()忽略不同的os.stat()签名?

时间:2011-11-08 03:21:48

标签: python file-comparison

filecmp()的Python 2文档说:

  

除非给出且为false,否则具有相同os.stat()签名的文件将被视为相等。

听起来两个文件除了os.stat()签名之外完全相同时会被视为不相等,但似乎并非如此,如运行以下代码片段所示:

import filecmp
import os
import shutil
import time

with open('test_file_1', 'w') as f:
    f.write('file contents')
shutil.copy('test_file_1', 'test_file_2')
time.sleep(5)  # pause to get a different time-stamp
os.utime('test_file_2', None)  # change copied file's time-stamp

print 'test_file_1:', os.stat('test_file_1')
print 'test_file_2:', os.stat('test_file_2')
print 'filecmp.cmp():', filecmp.cmp('test_file_1', 'test_file_2')

输出:

test_file_1: nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0,
  st_uid=0, st_gid=0, st_size=13L, st_atime=1320719522L, st_mtime=1320720444L, 
  st_ctime=1320719522L)
test_file_2: nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, 
  st_uid=0, st_gid=0, st_size=13L, st_atime=1320720504L, st_mtime=1320720504L, 
  st_ctime=1320719539L)
filecmp.cmp(): True

正如您所看到的那两个文件的时间戳 - st_atimest_mtimest_ctime - 明显不一样,但filecmp.cmp()表明两者都是相同。我误解了某些内容,或者filecmp.cmp()的实施或文档中是否存在错误?

更新

Python 3 documentation已被重新描述,目前说的是以下内容,恕我直言只是在改进意味着即使{{1}时更好地暗示具有不同时间戳的文件可能仍被视为相等的意义上的改进是真的。

  

如果为真,则具有相同os.stat()签名的文件为   被认为是平等的。否则,将比较文件的内容。

FWIW我认为简单地说出这样的话会更好:

  

如果为真,则仅在比较文件内容时进行比较   os.stat()   签名是不平等的。

2 个答案:

答案 0 :(得分:7)

你误解了文档。第2行说:

  

除非提供且为false,否则具有相同os.stat()签名的文件将被视为相等。

具有相同os.stat()签名的文件被认为是相同的,但logical inverse不是真的:具有不等os.stat()签名的文件不一定被认为是不相等的。相反,它们可能不相等,在这种情况下,比较实际文件内容。由于发现文件内容相同,filecmp.cmp()会返回True

根据第三个子句,一旦确定文件相同,它将缓存该结果,如果要求它再次比较相同的文件,则不会重新读取文件内容,只要那些文件'os.stat结构不会更改

答案 1 :(得分:1)

似乎“滚动你自己的”确实是产生理想结果所需要的。如果文档足够清晰,可以让随意的读者得出这个结论,那就太好了。

这是我目前使用的功能:

def cmp_stat_weak(a, b):
    sa = os.stat(a)
    sb = os.stat(b)
    return (sa.st_size == sb.st_size and sa.st_mtime == sb.st_mtime)