Python多目录项目跨子目录导入失败问题求助
看起来你遇到了Python模块导入的经典问题——当子目录之间需要互相导入时,默认的模块查找路径不包含其他子目录,所以会失败。我来一步步帮你解决这个问题:
首先先明确你的项目结构(我假设是这样):
project/ ├── sub1/ │ └── Thing.py # 里面有Thing类 └── sub2/ └── your_script.py # 你想在这里导入Thing的文件
第一步:把目录变成Python包
Python只会识别包含__init__.py文件的目录为可导入的包。所以先给每个子目录(包括根目录project)添加一个空的__init__.py文件,结构变成:
project/ ├── __init__.py ├── sub1/ │ ├── __init__.py │ └── Thing.py └── sub2/ ├── __init__.py └── your_script.py
这个文件不需要写任何内容,只是告诉Python这是一个包目录。
第二步:选择合适的导入方式
方式1:绝对导入(推荐,可读性强)
在sub2/your_script.py里写:
from sub1.Thing import Thing
但注意运行方式:你需要从project目录的父目录来运行脚本,用模块的方式启动:
python -m project.sub2.your_script
这种方式会把project的父目录加入Python的模块查找路径,让Python能找到sub1这个子包。
方式2:相对导入(适合包内部的模块引用)
如果你只是在项目内部的模块之间互相调用,可以用相对路径导入,在your_script.py里写:
from ..sub1.Thing import Thing
不过这种方式只能用模块方式运行(就是上面的python -m ...命令),不能直接双击或者用python sub2/your_script.py运行,否则会报错“attempted relative import with no known parent package”——因为直接运行脚本时,Python不知道它属于哪个父包。
方式3:临时添加项目根目录到查找路径(适合直接运行脚本)
如果习惯直接运行your_script.py,可以在脚本开头手动把项目根目录加入Python的模块查找路径:
import sys from pathlib import Path # 获取项目根目录的绝对路径(也就是project文件夹的路径) project_root = Path(__file__).parent.parent sys.path.append(str(project_root)) # 现在就能正常导入了 from sub1.Thing import Thing
这种方式不管你从哪个目录运行脚本,都能正确找到sub1模块。
方式4:把项目安装成可编辑包(专业项目推荐)
如果这是一个长期维护的项目,推荐把它安装成Python的可编辑包。在project目录下创建一个setup.py文件,内容如下:
from setuptools import setup, find_packages setup( name="project", version="0.1.0", packages=find_packages(), )
然后在project目录下运行命令:
pip install -e .
这样你的project包就会被链接到Python的全局包目录里,之后不管在哪个脚本里,都能直接写from sub1.Thing import Thing,完全不用操心路径问题。
额外建议:优先用类而不是全局变量
你提到试过用全局变量的写法,但还是出现导入问题——其实全局变量在多模块项目里更容易出现作用域混乱、导入顺序导致的未定义问题,用类来存储变量是更规范的做法,坚持这个方向没错。
内容的提问来源于stack exchange,提问作者ZachR

