我用Python 2.7.5运行下面的代码。 在Windows下:
import os, shutil, stat, time with open('test.txt', 'w') as f: pass # create an arbitrary file shutil.copy('test.txt', 'test2.txt') # copy it shutil.copystat('test.txt', 'test2.txt') # copy its stats, too t1 = os.lstat('test.txt').st_mtime # get the time of last modification for both files t2 = os.lstat('test2.txt').st_mtime print t1 # prints something like: 1371123658.54 print t2 # prints the same string, as expected: 1371123658.54 print t1 == t2 # prints False! Why?!
我期望两个时间戳(=浮动)是相等的(因为他们的string表示暗示),所以为什么t1 == t2
评估为False
?
另外,我无法用较less的代码来重现这种行为,即没有比较来自两个不同文件的通过os.lstat
检索的时间戳。 我有这种感觉,我错过了一些微不足道的东西…
编辑:进一步testing后,我注意到,它确实打印True
偶尔,但不是比每10次运行一次。
编辑2:按照larsmans的build议:
print ("%.7f" % t1) # prints eg 1371126279.1365688 print ("%.7f" % t2) # prints eg 1371126279.1365681
这提出了两个新的问题:
shutil.copystat
之后,为什么时间戳不相等? print
轮默认浮动?! 问题是在copystat
调用期间不同格式之间的转换。 这是因为Windows将文件时间存储为定点十进制格式,而Python将其存储为浮点二进制格式。 所以每次在两种格式之间进行转换时,都会失去一些准确性。 在copystat
呼叫期间:
os.stat
将Windows格式转换为Python的浮点格式。 一些准确性丢失了。 os.utime
来更新文件时间。 这将其转换回Windows格式。 一些准确性再次丢失,文件时间不一定与第一个文件相同。 当你自己调用os.lstat
,会执行第三个不准确的转换。 由于这些转换,文件时间不完全相同。
os.utime
的文档提到了这个:
请注意,您在此设置的确切时间可能不会由后续的stat()调用返回,具体取决于操作系统记录访问和修改时间的分辨率
关于你的第二个问题(为什么print
看起来显示为两个相同的值):将一个浮点值转换为一个字符串与str(f)
或print f
将四舍五入值。 要获得保证对不同浮点值唯一的值,请使用print repr(f)
。
from decimal import * print Decimal(t1) print Decimal(t2)
对t1和t2使用round()
尝试打印浮点时间差: print float.hex( t1 - t2)
结果:
0x1.0000000000000p-22 0x1.8000000000000p-21 0x0.0p+0 0x1.0000000000000p-20
我的2点猜测:输出的变化来自浮点表示偏差和舍入误差。 无论如何,当比较两个浮点数时,你应该总是使用一个epsilon值。
编辑:检查这个Python的bug 。
这是一个系统限制。 底层文件系统支持文件标记的纳秒分辨率,stat(2)也支持报告它们。 但是,utimes(2)在设置时仅支持微秒分辨率。
比较两个浮点数时,您最好使用微秒的分辨率。