直接运行 python main.py 会绕过uvicorn热重载机制,因--reload仅在uvicorn主进程启动时生效;正确做法是终端执行uvicorn main:app --reload,或ide中配置为module模式运行uvicorn。

直接运行 python main.py 会绕过热重载机制
Uvicorn 的 --reload 只在它自己作为主进程启动时才生效。如果你在代码里写 uvicorn.run("main:app", reload=True),再用 PyCharm 或 VSCode 点「运行」按钮,实际是 Python 解释器直接执行脚本 —— 此时 uvicorn 的文件监听器根本没机会接管进程生命周期。
常见错误现象:
- 控制台显示
INFO: Uvicorn running on http://...,但改完保存后毫无反应 - PyCharm Event Log 里出现
Restarting with reloader,但服务没重启 - 用
ps aux | grep uvicorn查不到子进程,只看到一个孤立的 python 进程
正确做法只有两种:
- 终端里手动运行:
uvicorn main:app --reload(确保当前目录是项目根) - 在 IDE 配置中明确使用
module模式:PyCharm 选「Module name」填uvicorn,参数写["main:app", "--reload"];VSCode 的launch.json里设"module": "uvicorn"
--reload 启用了,但文件改动仍不触发重启
Uvicorn 默认只监听当前工作目录(.)下的 Python 文件,且依赖系统级文件事件通知。一旦路径、权限或底层库出问题,监听就静默失效。
排查要点:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 确认运行命令是否带了
--reload-dir:比如项目结构含src/和api/,就得加--reload-dir ./src --reload-dir ./api - 检查
watchfiles是否装对:pip show watchfiles应输出版本号;若没装或版本太老(uvicorn[standard] 必须重装:pip install --force-reinstall uvicorn[standard] - WSL / Docker / Windows 上容易触发轮询失败:临时加环境变量
WATCHFILES_FORCE_POLLING=true,再试一次 - 杀毒软件或 OneDrive / Dropbox 实时同步可能拦截文件变更事件,可临时禁用测试
PyCharm 里配置了 --reload,但重载极慢或卡住
这不是 bug,是 PyCharm 对终端模拟和信号转发的限制导致 uvicorn 的子进程无法被正常 kill + fork。尤其在新版 PyCharm(2025.2+)和 uvicorn ≥0.22.0 组合下更明显。
实操建议:
- 优先降级 uvicorn:
pip install "uvicorn(0.21.1 是目前最稳的版本) - 运行配置中勾选
Emulate terminal in output console(但注意:ANSI 颜色日志会乱码) - 避免在 PyCharm 里「Debug」模式下开
--reload:调试时关掉--reload,改用断点 + 手动重启;热重载阶段切到「Run」模式 - 如果必须调试 + 热重载共存,改用
watchfiles run_process替代:watchfiles "uvicorn main:app" ./
--reload 和 --workers 一起用,为什么多进程消失了?
这是设计使然,不是故障。--reload 要求 uvicorn 以单进程模式运行,才能安全地 fork 新实例。只要命令里同时出现这两个参数,uvicorn 会直接忽略 --workers 并输出警告:WARNING: "workers" flag is ignored when reloading is enabled.
所以:
- 本地开发:只用
--reload,别加--workers - 想测多进程行为:关掉
--reload,改用--workers 4 --loop uvloop - 真要兼顾?用
hypercorn替代:hypercorn main:app --reload --workers 4(它支持两者共存)
真正容易被忽略的是:很多人在 pyproject.toml 或 Makefile 里固化了带 --workers 的命令,却忘了开发时该删掉它 —— 结果 reload 看似开着,实则被 silently disabled。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










