FastAPI运行导入项目模块的py文件报No module named 'app'如何解决
报No module named 'app'的核心原因是Python运行独立脚本时,模块搜索路径未包含app文件夹所在的项目根目录。uvicorn启动服务时会自动将当前工作目录加入模块搜索路径,因此导入正常;直接执行脚本时不会自动加载该路径,就无法识别项目内的自定义模块。
以下是几种可行的解决方式,按推荐优先级排序:
方案1:以模块模式运行脚本(无侵入,最推荐)
切换到项目根目录(即能直接看到app文件夹的目录层级),不要用文件路径直接执行脚本,而是将脚本作为项目模块通过-m参数运行,命令格式和导入模块的写法一致,不需要带.py后缀:
- 若
some.py直接放在项目根目录,执行:python -m some - 若
some.py放在项目的scripts等子目录下(如路径为scripts/some.py),执行:python -m scripts.some
该方式会自动将当前所在的项目根目录加入Python搜索路径,运行环境和uvicorn启动服务时完全一致,不会出现路径偏差问题。
方案2:执行命令时临时指定PYTHONPATH
切换到项目根目录,执行命令时临时将当前目录加入Python搜索路径,不同操作系统/终端的命令如下:
- Mac/Linux 终端:
PYTHONPATH=. python 你的脚本路径 - Windows CMD:
set PYTHONPATH=. && python 你的脚本路径 - Windows PowerShell:
$env:PYTHONPATH="."; python 你的脚本路径
举个例子,如果脚本在scripts/some.py路径下,Mac/Linux下直接执行PYTHONPATH=. python scripts/some.py即可正常导入模块。
方案3:脚本内手动注入搜索路径(仅适合临时调试)
在脚本的最顶部,所有项目内模块导入语句之前,添加代码将项目根目录加入搜索路径。
如果脚本放在项目根目录,添加如下代码:
import sys from pathlib import Path # 将当前脚本所在的项目根目录加入搜索路径 sys.path.append(str(Path(__file__).parent.resolve())) from app.core.config import settings if __name__ == '__main__': print('hello')
如果脚本放在scripts这类子目录,只需把路径拼接逻辑调整为往上跳一级即可:sys.path.append(str(Path(__file__).parent.parent.resolve()))
该方式需要给每个独立脚本都加冗余的路径处理代码,部署时换目录容易出问题,只建议临时调试小脚本时使用。
方案4:编辑模式安装项目(适合长期维护的项目)
在项目根目录新建pyproject.toml配置文件,写入基础配置:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "your-fastapi-project" version = "0.0.1" packages = ["app"]
激活虚拟环境后在项目根目录执行pip install -e .,将项目以可编辑模式安装到当前虚拟环境。安装完成后,不管在什么目录位置运行独立脚本,只要处于该虚拟环境下,都能正常导入app下的所有模块,和第三方库的导入逻辑完全一致。
内容的提问来源于stack exchange,提问作者sean k

