我在Python中有一个C ++代码生成器,可以生成许多源文件。大多数情况下,只有一个文件发生更改,但由于生成器会重新生成所有文件,因此它们都会重建。有没有办法让Python不覆盖文件,或者让cmak使用校验和来查看需要重建的内容而不仅仅是使用文件日期?
我认为这样的事情在Python中很容易:如果我可以替换
with open('blah', 'w') as f:
用这个:
with open_but_only_overwrite_if_total_output_is_different('blah', 'w') as f:
实现这一目标的好方法是什么?
答案 0 :(得分:4)
结合Neil G,Petr Viktorin,gecco和joel3000的代码和想法:
import contextlib
@contextlib.contextmanager
def write_on_change(filename):
with tempfile.NamedTemporaryFile(delete=False) as f:
yield f
tempname = f.name
try:
overwrite = not filecmp.cmp(tempname,filename)
except (OSError,IOError):
overwrite = True
if overwrite:
shutil.copyfile(tempname,filename)
os.unlink(tempname)
一些小的补充(希望改进):
shutil.copyfile
仅将tempname
的内容复制到。{1}}中
filename
,同时保留文件权限和文件等元数据
所有权。filecmp.cmp
检查文件的大小
如果尺寸不匹配,则返回False
。那可能很不错
加速,如果文件很大,一个附加的东西
结束。它还一次读取并比较bufsize = 8*1024个字节,
而不是一次一行。 bufsize
通常会大于a
行,这将导致更少的读取。答案 1 :(得分:3)
我建议你像这样编写我们自己的文件对象:
__enter__
:创建临时文件__exit__
:比较临时文件的内容与旧文件(如果存在)如果它们不相同,则用临时文件替换旧文件 本文非常有助于理解with
声明:Understanding Python's "with" statement
答案 2 :(得分:3)
使用filecmp - http://docs.python.org/library/filecmp.html。
将新文件写入tmp目录,与工作目录进行比较 ,并转移更改的文件。然后删除tmp。
答案 3 :(得分:0)
最简单的方法是在Python中完成cmake所做的事情:让生成器检查输入是否比输出更新,并且仅在生成时才生成。
以下是我用于类似内容的代码段:
if (os.path.exists(output) and
os.path.getmtime(source) <= os.path.getmtime(output)):
print "Generated output %s is up-to-date." % output
return