Python项目开发结构,以及如何包内如何相互导入及如何运行命令行
问题引入
我是一个从零开始的小白入手python项目开发,在开过过程中遵循着,现在最主流的项目结构如下所示:
其中crag就是我的项目包名.
之后再document.py中使用了config.py文件中的一些函数,使用的导入语句为:from crag.config import CHROMA_PERSIST_DIR
之后再项目的根目录下执行命令行:
(.venv)PS E:\code\VSCode\CRAG>python .\src\crag\document.py Traceback(most recent call last): File"E:\code\VSCode\CRAG\src\crag\document.py", line6,in<module>from .configimportCHROMA_PERSIST_DIR, EMBEDDING_MODEL,MODEL_DIR,DATA_DIR ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ImportError: attempted relativeimportwith no known parent package就会报各种各样的错误.之后博主花了许多功夫菜搞懂了在python项目开发过程中最正确的使用方法.
解决问题
刚刚提到的src布局(src-layout)是目前 Python 社区(包括 PyPA 官方)最推荐的项目结构,因为它能有效防止“测试代码意外导入源码”等问题。
让我们一步一步讲解python项目开发过程中的包的导入和命令行的书写.
1. 为什么使用src布局?
在src布局中,你的结构通常长这样:
CRAG/ ├── pyproject.toml # 项目配置文件(非常重要) ├── src/ │ └── crag/ # 真正的源码包 │ ├── __init__.py │ ├── config.py │ └── document.py ├── tests/ # 测试代码 └── .venv/当你安装这个项目时,pip会将src下的crag文件夹安装到你的 Python 环境中。发布时,用户不会看到src这个文件夹,他们只能看到crag库。
2. 怎么写导入(内部相互引用)?
无论是在开发还是安装后,请统一使用“绝对导入”,不要使用相对导入。
如果你的源码包名字是crag,那么在document.py中引用config.py时,永远这样写:
# 无论你是从哪里运行,都从包的最顶层开始写fromcrag.configimportCHROMA_PERSIST_DIR,...3. 如何在开发中运行代码?
为了让 Python 能够识别src目录,最标准的方法是以可编辑模式(Editable Mode)安装你的项目。
第一步:在根目录创建pyproject.toml
在CRAG/目录下创建一个简单的pyproject.toml文件:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "crag" version = "0.1.0"第二步:安装项目
在CRAG/目录下(确保你的虚拟环境已激活),执行:
pipinstall-e.-e代表editable(可编辑)。- 这句话的意思是:告诉 Python,“把我当前文件夹下的
src目录加入到 Python 的搜索路径中”。 - 好处:现在你修改了代码,不需要重新安装,直接生效。
第三步:如何运行
安装后,你就不再依赖“路径”了,而是直接调用这个库。此时,你可以:
方法 A:直接在任何地方写 Python 脚本运行
因为你已经把crag安装到了环境中,你可以在任何地方运行:
# 比如在根目录建一个 run.pyfromcrag.documentimportsome_function some_function()方法 B:使用python -m
# 只要安装了 -e . ,你直接这样运行就行,不需要管文件路径python-mcrag.document4. 总结:最佳实践工作流
- 项目内部引用:全部使用绝对路径,例如
from crag.utils import ...,不要用from .utils import ...。 - 开发环境配置:每次新建项目,第一时间在根目录创建
pyproject.toml,并运行pip install -e .。 - 开发与发布的区别:
- 开发时:
pip install -e .让你的代码“热更新”。 - 发布时:你打包工具(如
build)会自动处理src,把crag目录提取出来分发给用户。用户安装后,他们运行代码的方式和你一模一样,不需要知道src文件夹的存在。
- 开发时:
给你的具体操作建议:
- 把
document.py里的from .config改成from crag.config。 - 在
CRAG根目录建一个pyproject.toml。 - 执行
pip install -e .。 - 以后运行代码统一使用
python -m crag.main这种格式。
这样配置后,你的 VSCode 警告也会消失,导入逻辑也会变得非常清晰且符合工业标准。
