## 绝对导入 绝对导入是从项目的根目录开始引用模块的方式。无论你的当前文件位于项目的哪个位置,绝对导入的路径都是固定的。 ### 示例 假设你有以下项目结构: ```Java myproject/ ├── app/ │ ├── __init__.py │ ├── main.py │ ├── interfaces/ │ │ ├── __init__.py │ │ └── api/ │ │ ├── __init__.py │ │ └── essay_controller.py │ └── domain/ │ ├── __init__.py │ └── services/ │ ├── __init__.py │ └── essay_service.py ``` 在 `essay_controller.py` 中使用绝对导入: ```python # 绝对导入 from app.domain.services.essay_service import EssayService ``` 绝对导入的特点: - 路径从项目根目录开始 - 不受文件位置影响,在任何地方都可以使用相同的导入语句 - 更清晰,容易理解代码之间的依赖关系 - 需要项目根目录在 Python 的模块搜索路径中 ## 相对导入 相对导入是基于当前文件的位置来引用模块的方式。使用点号(`.`)来表示相对路径。 ### 示例 在同样的项目结构下,在 `essay_controller.py` 中使用相对导入: ```python # 相对导入 from ....domain.services.essay_service import EssayService # 向上四级,再向下到domain/services ``` 或者在 `main.py` 中: ```python # 相对导入 from .interfaces.api.essay_controller import router as essay_router # 当前目录下的interfaces/api ``` 相对导入的特点: - 使用点号(`.`)表示相对路径 - 一个点(`.`)表示当前包 - 两个点(`..`)表示上一级包 - 更多点表示更上级的包 - 依赖于文件在包结构中的位置 - 如果文件移动,相对导入可能需要更改 - 只能在包内使用,不能在直接运行的脚本中使用 ## 你项目中的问题 在你的项目中,出现了混合使用两种导入方式的情况: 1. 在 `main.py` 中使用相对导入: ```python from interfaces.api.essay_controller import router as essay_router ``` 2. 而在 `essay_controller.py` 中使用绝对导入: ```python from app.application.use_cases.get_sentence_use_case import GetSentenceUseCase ``` 当你在容器中运行 `python app/main.py` 时: - Python 将 `/app` 目录添加到模块搜索路径 - `main.py` 中的相对导入可以找到 `interfaces.api.essay_controller` - 但 `essay_controller.py` 中的绝对导入找不到 `app` 模块,因为 Python 在寻找 `/app/app` 而不是将 `/app` 识别为 `app` 模块 ## 最佳实践 1. **保持一致性**:在整个项目中使用同一种导入方式 2. **推荐使用绝对导入**: - 更清晰,不受文件位置影响 - 在大型项目中更容易维护 3. **正确设置 Python 路径**: - 确保项目根目录在 Python 的模块搜索路径中 - 可以通过设置 `PYTHONPATH` 环境变量或在代码中修改 `sys.path` 4. **使用 `__init__.py` 文件**: - 在每个目录中添加 `__init__.py` 文件,使其成为一个 Python 包 - 这样 Python 可以正确识别和导入包结构 通过我们的修改(更改工作目录和设置 `PYTHONPATH`),我们解决了这个问题,使 Python 能够正确找到所有模块。