如何监视Python文件的更改?
我想在我的Python网页应用程序中,如果代码有变化就重新启动它。但是可能会有很多文件会被修改,因为导入的模块中的文件也可能会改变……
怎么才能获取到被导入的包或模块的实际文件名呢?
有没有什么方法可以有效地检测到被修改的Python文件?有没有相关的库可以使用?
5 个回答
1
我不太确定在你的情况下如何实现“重新加载应用程序”的操作;使用内置的 reload
可能不够用来重新加载已经改变的模块。
不过,关于如何检测是否有变化,下面是一种可能的方法。
- 大多数 Python 模块都有一个
__file__
属性。 - 所有加载的模块都存储在
sys.modules
中。 - 我们可以定期检查
sys.modules
,逐个查看每个模块在磁盘上的变化。
有时候 __file__
指向的是 .pyc
文件,而不是 .py
文件,所以你可能需要去掉最后的 c。有时候 .pyc
文件存在,但 .py
文件却不存在;在一个健壮的系统中,你需要考虑到这种情况。
下面是一个简单的代码示例来实现这个功能(并不健壮):
_module_timestamps = {}
_checking = False
def run_checker():
global _checking
_checking = True
while _checking:
for name, module in sys.modules.iteritems():
if hasattr(module, '__file__'):
filename = module.__file__
if filename.endswith('.pyc'):
filename = filename[:-1]
mtime = os.stat(filename).st_mtime
if name not in _module_timestamps:
_module_timestamps[name] = mtime
else:
if mtime > _module_timestamps[name]:
do_reload(name)
else:
'module %r has no file attribute' % (name,)
time.sleep(1)
def do_reload(modname):
print 'I would reload now, because of %r' % (modname,)
check_thread = threading.Thread(target=run_checker)
check_thread.daemon = True
check_thread.start()
try:
while 1:
time.sleep(0.1)
except KeyboardInterrupt:
print '\nexiting...'
1
gamin 是另一个选择,它对Linux的依赖稍微少一些。
5
顺便提一下,我正在做一个项目,地址是 http://github.com/gorakhargosh/watchdog,它正好可以实现这个功能。
希望对你有帮助。