绝对导入无法同时适配Uvicorn运行与测试环境问题求助
解决方案:导入路径冲突问题
问题核心
你的问题本质是Python模块搜索路径(sys.path)在不同运行场景下的差异:
- 执行
pytest时,主目录会被自动加入sys.path,所以poetry_demo作为顶层包能被识别,绝对导入正常。 - 进入
poetry_demo目录运行uvicorn app:app时,当前目录(poetry_demo)被加入sys.path,Python找不到poetry_demo这个包(因为它就在当前目录里,不是子包)。
可行解决方案
方案1:从主目录运行Uvicorn(最简便)
不要进入poetry_demo目录,直接在主目录执行命令:
uvicorn poetry_demo.app:app --reload
这样Python会把主目录加入sys.path,poetry_demo作为顶层包能被正确识别,app.py里的绝对导入可以保留不变,同时pytest的运行也不受影响。
方案2:手动添加父目录到Python路径(临时hack)
如果必须在poetry_demo目录内运行,可以在app.py的最开头添加代码,手动把主目录加入sys.path:
import sys from pathlib import Path # 获取当前文件的父目录的父目录(即主目录) sys.path.append(str(Path(__file__).parent.parent)) # 后续的绝对导入保持不变 from fastapi import FastAPI from poetry_demo.domain.items.controller import ItemsController from poetry_demo.domain.items.service import ItemsService app = FastAPI() app.include_router(ItemsController(service=ItemsService).router, prefix="/items")
这个方法能临时解决路径问题,但不推荐长期使用,因为依赖硬编码的路径逻辑。
方案3:将项目配置为可安装包(最规范)
利用Poetry把poetry_demo做成可安装的Python包,这是Python项目的标准做法:
- 在
pyproject.toml中确保包配置正确:
[tool.poetry] name = "poetry_demo" version = "0.1.0" description = "" authors = ["Your Name <your.email@example.com>"] packages = [{ include = "poetry_demo" }] # 可选:添加启动脚本 [tool.poetry.scripts] start-app = "poetry_demo.app:app"
- 执行安装命令,把包安装到Poetry的虚拟环境中:
poetry install
- 之后无论在哪个目录,都可以通过以下命令运行服务:
poetry run uvicorn poetry_demo.app:app --reload # 或者用脚本 poetry run start-app
这种方式下,poetry_demo作为环境中的正式包,无论是运行服务还是执行pytest,导入路径都能正常工作,是最推荐的长期解决方案。
内容的提问来源于stack exchange,提问作者Tomek Buszewski
相关产品推荐
相关产品推荐

