Skip to main content

在 python 中简单、现代的文件监视和代码重载。

项目描述

看门神

CI 覆盖范围 皮皮 执照

在 python 中简单、现代的文件监视和代码重载。


通知 - 包重命名为watchfiles

请注意:此包 (watchgod) 已重命名为watchfiles。请替换watchgodwatchfiles,请参阅迁移指南 以获取有关切换的帮助和说明。

除了更好的名字之外,watchfiles它还有一个基于 rust-notify 的全新后端,这使得监视文件系统事件的效率更高。

该名称下的软件包watchgod将不会进一步开发,只会收到关键的安全修复程序。


用法

要监视目录中的更改:

from watchgod import watch

for changes in watch('./path/to/dir'):
    print(changes)

运行函数并在代码更改时重新启动它:

from watchgod import run_process

def foobar(a, b, c):
    ...

run_process('./path/to/dir', foobar, args=(1, 2, 3))

run_process使用PythonWatcher所以只有对 python 文件的更改才会提示重新加载,请参阅下面的自定义观察程序。

如果您需要有关更改事件的通知以及重新启动进程,您可以使用callback参数传递一个函数,该函数将在每次文件更改时使用一个参数调用:文件更改集。

安装

pip install watchgod

异步方法

watchgod带有 : 的异步等效项,watchawatch使用 aThreadPoolExecutor来遍历文件。

import asyncio
from watchgod import awatch

async def main():
    async for changes in awatch('/path/to/dir'):
        print(changes)

asyncio.run(main())

还有一个 : 的异步等价物,run_processarun_process反过来使用awatch:

import asyncio
from watchgod import arun_process

def foobar(a, b, c):
    ...

async def main():
    await arun_process('./path/to/dir', foobar, args=(1, 2, 3))

asyncio.run(main())

arun_process使用PythonWatcher所以只有对 python 文件的更改才会提示重新加载,请参阅下面的自定义观察程序。

的签名arun_process几乎相同,run_process除了可选callback参数必须是协程,而不是函数。

自定义观察者

watchgod带有以下观察程序类,可以通过上述watcher_cls 任何方法的关键字参数使用。

例如:

for changes in watch(directoryin, watcher_cls=RegExpWatcher, watcher_kwargs=dict(re_files=r'^.*(\.mp3)$')):
   print (changes)

有关更多详细信息,请查看 checkout watcher.py,这非常简单。

  • AllWatcher基本观察者,检查所有文件的变化。

  • DefaultWatcher默认情况下由watchand使用的监视程序awatch,通常被忽略的文件,如*.swp*.pyc*~与目录如 .git.

  • PythonWatcher特定于 python 文件,只有*.py*.pyx文件*.pyd被监视。

  • DefaultDirWatcher是 和 的DefaultWatcher基础DefaultDirWatcher。它会忽略一些常规目录。

如果这些类还不够,你可以定义自己的观察者,特别是你会想要覆盖should_watch_dirshould_watch_file。除非你在做一些非常奇怪的事情,否则你会想要继承自DefaultDirWatcher.

请注意,不会报告与目录相关的事件(例如创建目录),但会报告新目录中的新文件。

命令行界面

watchgod还附带了一个用于运行和重新加载 python 代码的 CLI。

假设你有foobar.py

from aiohttp import web

async def handle(request):
    return web.Response(text='testing')

app = web.Application()
app.router.add_get('/', handle)

def main():
    web.run_app(app, port=8000)

当当前目录中的任何文件更改为:时,您可以运行它并重新加载它:

watchgod foobar.main

如果您需要忽略某些文件或目录,可以使用参数 --ignore-paths.

运行watchgod --help以获得更多选项。watchgod也可以作为 python 可执行模块通过python -m watchgod ....

为什么不支持inotify / kqueue / fsevent / winapi

watchgod(目前)使用文件轮询而不是操作系统内置的文件更改通知。

这不是疏忽,而是基于以下理由的决定:

  1. 轮询“足够快”,尤其是在 PEP 471 引入 fast 之后scandir。对于像 TutorCruncher 代码库这样具有 850 个文件和 30 万行代码的相当大的项目,watchgod可以在大约 24 毫秒内扫描整个树。扫描间隔为 400 毫秒,大约是一个 CPU 的 5%——开发过程中完全可以接受的负载。
  2. 线索就在标题中,至少有 4 个不同的文件通知系统可以集成,其中大多数都不是微不足道的。这就是我们在不同操作系统版本之间进行更改之前的全部内容。
  3. 当您想要对更改进行分组或“去抖动”时,轮询很有效。假设您正在运行一个开发服务器,并且您在 git 中更改了分支,100 个文件发生了变化。你想重新加载开发服务器 100 次还是一次?正确的。定期轮询可能会将这些更改归为一个事件。如果您正在接收事件流,则需要在收到第一个事件时延迟执行重新加载,以查看它是否是一组文件更改的一部分。这不是微不足道的。

话虽如此,我可能仍然使用 rust 的“通知”板条箱来完成繁重的文件监视,请参阅#25

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

watchgod-0.8.2.tar.gz (13.9 kB 查看哈希

已上传 source

内置分布

watchgod-0.8.2-py3-none-any.whl (12.3 kB 查看哈希

已上传 py3