如何从非子目录的不同文件夹导入模块?项目导入报错求解
首先我得先假设一个最常见的项目结构(毕竟你没给出具体目录结构,但这两个错误基本对应下面这种布局):
my_project/ ├── api/ │ └── api.py ├── backend/ │ └── backend.py └── models/ └── some_model.py
为什么会出现这两个错误?
1. ModuleNotFoundError: No module named 'models'
当你直接运行api/api.py或者backend/backend.py时,Python会把脚本所在的目录(比如api/)加入到模块搜索路径sys.path里,而不是项目根目录my_project/。这时候Python找不到models这个包,因为它不在当前的搜索路径里,自然就报错了。
2. ValueError: attempted relative import beyond top-level package
如果你尝试用相对导入,比如在api.py里写from ..models import some_model,直接运行脚本的话,Python会把api/当成顶级包。这时候..意味着要跳出顶级包,这在Python的模块规则里是不允许的,所以触发这个错误。相对导入只有在把整个项目当作一个包来运行时才有效,不能直接运行子目录里的脚本。
如何正确实现跨文件夹导入?
这里有三种常用的解决方案,从临时调试到生产环境都覆盖:
方案1:临时将项目根目录加入搜索路径(适合快速调试)
在api.py和backend.py的最顶部添加以下代码,手动把项目根目录加到Python的模块搜索路径里:
import sys from pathlib import Path # 获取项目根目录(my_project/) project_root = Path(__file__).parent.parent sys.path.append(str(project_root)) # 现在就可以正常导入了 from models.some_model import your_function_or_class
这个方法简单直接,但属于临时解决方案,不推荐在生产环境长期使用。
方案2:将项目转为可安装包(生产环境推荐)
这是最规范的做法,把你的项目变成一个可安装的Python包,这样无论在哪里都能正常导入模块。
在项目根目录
my_project/下创建setup.py文件(或者更现代的pyproject.toml):# setup.py示例 from setuptools import setup, find_packages setup( name="my_project", version="0.1.0", packages=find_packages(), )在终端里进入
my_project/目录,执行以下命令安装本地开发版本:pip install -e .-e参数表示"可编辑模式",之后你修改代码不需要重新安装。现在在
api.py和backend.py里就可以直接导入了:from models.some_model import your_function_or_class
方案3:用模块方式运行脚本(适合相对导入场景)
如果你坚持想用相对导入(比如from ..models import some_model),不能直接运行api.py,而是要从项目根目录用python -m的方式运行:
cd my_project/ python -m api.api
这时候Python会把my_project/当作顶级包,api是它的子包,相对导入的..就能正确定位到models包了。
内容的提问来源于stack exchange,提问作者Gasp0de

