如何监视Python文件的更改?

4 投票
5 回答
5068 浏览
提问于 2025-04-16 05:01

我想在我的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,它正好可以实现这个功能。

希望对你有帮助。

撰写回答