You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生产级Python项目导入最佳实践及多场景导入、项目结构优化问询

生产级Python项目导入最佳实践及多场景导入、项目结构优化问询

兄弟,你的项目结构其实已经摸到生产级的门槛了,先给你点个赞!不过咱们可以再细化优化下,同时彻底解决你头疼的导入问题,分点给你说清楚:

一、当前项目结构的优化建议

你的现有结构已经很规范了,只需要补充两个关键部分就更完善:

  • 新增tests/目录:放在项目根目录下,专门存放单元测试、集成测试文件,这是生产级项目的标配;
  • 补充依赖配置文件:比如requirements.txt(简单场景)或者pyproject.toml(推荐,符合PEP621标准),用来管理项目依赖,方便部署和协作;
  • 小调整:把src/settings.env移到项目根目录,配合python-dotenv库加载环境变量,这样更符合行业惯例,也方便在不同环境(开发/测试/生产)切换配置。

优化后的结构大概是这样:

my_project/
├── Dockerfile
├── Makefile
├── run.py
├── .env  # 原src/settings.env移到这里
├── requirements.txt
├── pyproject.toml
├── data/
│   ├── raw/
│   └── processed/
├── src/
│   ├── __init__.py
│   ├── config.py 
│   └── response/ 
│       ├── __init__.py
│       ├── llm.py
│       ├── instances.py
│       └── get_response.py
└── tests/
    ├── __init__.py
    ├── test_response.py
    └── test_config.py

二、不同场景下的导入解决方案

1. 运行tests目录的测试

  • 用pytest作为测试框架(生产级项目几乎都用它),直接在项目根目录运行pytest即可,它会自动识别src作为源码目录,测试文件里可以直接用绝对导入:
    # tests/test_response.py
    from src.response.llm import get_completion
    from src.response.instances import MyClass
    
    def test_get_completion():
        assert get_completion("test") is not None
    
  • 如果需要更细致的配置,可以在pyproject.toml里添加:
    [tool.pytest.ini_options]
    testpaths = ["tests"]
    pythonpath = ["."]
    

2. 直接执行文件夹内的文件(开发/调试)

绝对不要反复修改导入语句! 用以下两种方法解决:

方法一:使用相对导入(包内部模块间)

在src内部的模块里,用相对路径导入同包或父包的模块,比如:

  • 在src/response/get_response.py里导入同目录的llm:
    from .llm import get_completion
    
  • 在src/response/get_response.py里导入上层的config:
    from ..config import Config
    

这种方式的好处是,只要src被Python识别为一个包,不管从哪里运行都能正常导入。

方法二:把项目根加入Python路径

在单个文件的if __name__ == '__main__'块开头,手动把项目根目录加到sys.path里,比如在src/response/llm.py中:

def get_completion(prompt):
    # 你的实现代码
    return f"Response to: {prompt}"

if __name__ == '__main__':
    import sys
    from pathlib import Path
    # 根据当前文件位置,向上回溯找到项目根(my_project)
    project_root = Path(__file__).parent.parent.parent
    sys.path.append(str(project_root))
    
    # 现在可以正常导入其他模块
    from src.response.instances import MyClass
    # 测试代码
    test_result = get_completion("Hello LLM")
    print(test_result)

3. 使用if __name__ == '__main__'块做本地测试

结合上面的相对导入+路径配置,或者用更便捷的可编辑安装方式:
在项目根目录运行:

pip install -e .

这会把你的src目录作为一个可编辑的Python包安装到环境中,之后不管你在哪个目录运行代码,都能直接用绝对导入,比如在src/response/instances.py里:

class MyClass:
    def __init__(self):
        self.name = "MyClass Instance"

if __name__ == '__main__':
    # 直接导入其他模块,无需手动加路径
    from src.response.llm import get_completion
    obj = MyClass()
    print(obj.name)
    print(get_completion("Test prompt"))

三、核心疑问解答

Q:是否需要每次修改导入语句?

完全不需要!只要用上面提到的相对导入、可编辑安装或设置PYTHONPATH三种方式中的一种,就能统一导入逻辑,不用反复修改。

Q:把项目根加到Python路径是最佳方案吗?

如果是开发阶段,可编辑安装是最佳选择,它最符合Python包的规范,也能避免手动管理路径的麻烦;如果是临时调试,手动加sys.path或者设置环境变量PYTHONPATH也很方便:

  • Linux/macOS终端:
    export PYTHONPATH=/full/path/to/my_project
    
    可以把这条命令加到~/.bashrc或~/.zshrc里,永久生效。
  • Windows系统:
    在系统环境变量里新增PYTHONPATH,值为项目根目录的绝对路径。

Q:如何让脚本从任意位置运行?

最推荐的方式是可编辑安装(pip install -e .),它把你的项目变成了正式的Python包,Python会全局识别src下的模块,不管你在哪个目录运行python src/response/llm.py或者python run.py,导入都能正常工作。

另外,也可以在run.py里做入口统一管理,所有其他模块都通过run.py调用,这样只要从项目根运行run.py即可,内部模块用相对导入,也能保证稳定性。

备注:内容来源于stack exchange,提问作者vossi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:44:52