Python项目目录重构后跨模块导入失败的问题求助
各位好,我最近重构了Python项目的目录结构,结果遇到了模块导入的问题,折腾了好一阵还是没解决,想请教下大家的思路。
先给大家看下我的项目结构:
project/ ├── src/ │ ├── main.py │ ├── pdfs/ │ │ ├── create_pdf1.py │ │ ├── create_pdf2.py │ │ ├── create_pdf3.py │ │ ├── create_pdf4.py │ │ ├── create_pdf5.py │ │ └── merge_pdfs.py │ ├── entities/ │ │ ├── entitie1.py │ ├── utils/ │ │ └── helpers.py ├── aux/ │ ├── pdf_aux1.pdf │ └── pdf_aux2.pdf ├── out/ ├── result1.pdf └── result2.pdf
我现在在src/pdfs/create_pdf1.py里尝试导入entities/entitie1.py中的几个类,代码是:
from entities.entitie1 import Legajo, Persona, Domicilio, Empresa
但运行时直接报错:
Traceback (most recent call last): File "c:\Users\ricar\project\src\pdfs\create_pdf1.py", line 3, in <module> from entities.entitie1 import Legajo, Persona, Domicilio, Empresa ModuleNotFoundError: No module named 'entities'
后来我改成相对导入试试:
from ..entities.entitie1 import Legajo, Persona, Domicilio, Empresa
结果又出现新错误:
ImportError: attempted relative import with no known parent package
补充个背景:之前所有模块都直接放在src根目录下的时候,导入完全没问题,就是这次把文件分到子文件夹后就出问题了。
可能的解决方法:
我整理了几个常见的解决思路,大家可以参考:
手动添加项目路径到Python搜索路径
在create_pdf1.py的开头加上这段代码,把src目录添加到sys.path里,这样Python就能找到entities模块了:import sys import os # 获取当前文件所在目录的上级目录(也就是src目录) src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if src_path not in sys.path: sys.path.append(src_path)之后再用原来的
from entities.entitie1 import ...导入语句就可以正常工作了。以包的形式运行脚本
相对导入需要模块被当作包的一部分来加载,而不是直接运行脚本。你可以切换到项目的根目录(也就是project/文件夹下),然后用以下命令运行:python -m src.pdfs.create_pdf1这时候Python会把
src识别为一个包,相对导入from ..entities.entitie1 import ...就能正常生效了。添加
__init__.py文件(可选但推荐)
虽然Python 3.3+支持命名空间包,但在每个子目录下添加一个空的__init__.py文件,可以让Python更明确地把这些目录识别为包。你可以在src/、src/pdfs/、src/entities/、src/utils/这些目录下都创建一个空的__init__.py文件,这样结构会更清晰,也能避免一些潜在的导入问题。
为什么之前没问题?
之前所有文件都在src根目录下,当你直接运行脚本时,Python会把当前脚本所在的目录(也就是src)加入到sys.path中,所以能直接找到同目录下的其他模块。但现在文件分到了子文件夹,create_pdf1.py所在的src/pdfs目录不在sys.path里,自然找不到上级目录的entities模块;而直接运行脚本时,Python会把它当作顶级脚本,没有父包的概念,所以相对导入会失败。
备注:内容来源于stack exchange,提问作者Ricman1029

