日志显示 * restarting with stat 却不重启,说明 flask 正在使用低效的轮询机制检测文件修改,该机制在 wsl2、docker、nfs 或启用“安全写入”的 ide(如 vs code)中失效;安装 watchdog 可启用操作系统原生事件监听(如 inotify),实现毫秒级变更捕获并自动重启。

为什么日志显示 * Restarting with stat 却不重启
这说明 Flask 正在用轮询方式检测文件修改,而 stat 模式在 WSL2、Docker、NFS 或某些 IDE(如 VS Code 启用“安全写入”时)下根本看不到保存动作。它每秒检查一次时间戳,但这些环境里文件 mtime 可能延迟更新或被临时文件覆盖干扰,导致变更“隐身”。你改了 app.py,Flask 就是不响应——不是代码错了,是监听机制失效了。
pip install watchdog 是最直接有效的修复
watchdog 不是锦上添花的插件,它是让 debug 模式真正可用的基础设施。它启用操作系统原生事件监听(Linux 用 inotify,macOS 用 FSEvents),毫秒级捕获保存操作,绕过所有 stat 的缺陷。
- 执行
pip install watchdog,无需改任何代码、配置或启动命令 - 再次运行
flask run,日志中会从* Restarting with stat变成* Restarting with watchdog (inotify) - 此时改
app.py、templates/index.html甚至static/style.css都能触发重启(注意:静态文件变更是否生效取决于你是否启用了模板热重载,见下一条)
flask run 和 app.run(debug=True) 别混用
你可能同时做了两件事:在代码里写了 app.run(debug=True),又在终端敲了 flask run。这两套机制冲突,reloader 容易静默挂掉。官方 CLI 方式(flask run)才是推荐路径,它自动读取 .env 中的 FLASK_DEBUG=1 和 FLASK_APP=app,更稳定。
- 删掉代码里的
if __name__ == '__main__': app.run(...)块 - 确保项目根目录有
.env文件,内容为:FLASK_APP=app和FLASK_DEBUG=1 - 统一用
flask run启动,别再python app.py
改 HTML/CSS/JS 不重启?这是正常设计,不是 bug
Flask 默认只监听 .py 文件变更来触发服务重启。模板和静态资源修改后不重启,是因为它们本就不该影响 Python 进程生命周期——浏览器会直接加载新文件(前提是没缓存)。如果你发现改了 templates/index.html 刷新页面却没变,大概率是浏览器缓存或开发服务器没正确返回新内容,不是重载器问题。
- 确认你在路由里用了
render_template('index.html'),而不是硬编码 HTML 字符串 - 刷新时按
Ctrl+Shift+R(强制重载),或禁用浏览器缓存(DevTools → Network → Disable cache) - 如果真需要改模板也触发重启(比如调试 Jinja 逻辑),watchdog 安装后默认就支持,无需额外配置
最容易被忽略的一点:watchdog 在 Docker 或 WSL2 里也能工作,但 WSL2 用户得确保代码放在 /home/xxx/ 下,而不是 /mnt/c/ ——后者是 Windows 文件系统挂载点,inotify 事件不可用。











