文章目录
- [用 `pip install -e .` 开发时,Python 项目一般长什么样?](#用
pip install -e .开发时,Python 项目一般长什么样?) -
- 可编辑安装在干什么?
- [两种常见布局:平铺 vs `src/`](#两种常见布局:平铺 vs
src/) -
- [1. 平铺布局(flat / traditional)](#1. 平铺布局(flat / traditional))
- [2. `src/` 布局(更推荐用于库)](#2.
src/布局(更推荐用于库))
- [目录与命名习惯(和 PEP 的关系)](#目录与命名习惯(和 PEP 的关系))
- [现代配置:`pyproject.toml` + 可编辑安装](#现代配置:
pyproject.toml+ 可编辑安装) -
- 平铺布局示例(setuptools)
- [`src/` 布局示例(setuptools)](#
src/布局示例(setuptools))
- [和旧式 `setup.py` 的对比(了解即可)](#和旧式
setup.py的对比(了解即可)) - 最小可运行心智模型
- 小结
用 pip install -e . 开发时,Python 项目一般长什么样?
可编辑安装在干什么?
pip install -e . 里的 -e 表示 editable install(可编辑安装) :不会把代码复制进 site-packages,而是在那里放一个指向你项目根目录的链接(或等价机制)。你改源码后,不用反复重装 ,已安装的包就会用到最新代码。适合库、框架和需要被其它项目 import 的包。
💡 举个栗子🌰 你正在开发一个工具包 my_tool:
要点:"点" . 表示当前目录 ;pip 会在该目录里找安装说明(通常是 pyproject.toml,或旧的 setup.py / setup.cfg)。
两种常见布局:平铺 vs src/
1. 平铺布局(flat / traditional)
项目根目录下直接放包目录,例如:
text
myproject/
├── pyproject.toml # 或 setup.py
├── README.md
├── LICENSE
├── mypackage/ # 真正的 Python 包(可 import 的名字)
│ ├── __init__.py
│ ├── core.py
│ └── submod/
│ └── __init__.py
├── tests/
│ └── test_core.py
└── docs/
- 优点:简单、路径短。
- 缺点:容易在测试时"误 import 到当前目录的半成品",和装到环境里的包混淆;CI 里若没装好包,有时测的是本地文件夹而不是安装结果。
2. src/ 布局(更推荐用于库)
把可分发代码放进 src/ 下面:
text
myproject/
├── pyproject.toml
├── README.md
├── LICENSE
├── src/
│ └── mypackage/ # 包在 src 下
│ ├── __init__.py
│ └── ...
├── tests/ # 常放在根目录,与 src 并列
└── docs/
- 优点 :强制通过"已安装"的路径加载包,减少导入混乱,和 pytest 文档 里常见的建议一致。
- 缺点:多一层目录,配置里要写清楚包路径(见下文)。
两种布局都可以用 pip install -e .,差别主要在 工具怎么找到包。
目录与命名习惯(和 PEP 的关系)
| 类型 | 习惯 | 说明 |
|---|---|---|
| 项目根目录 | myproject、django、requests 等 |
仓库名可与 PyPI 包名一致或接近,无强制规范。 |
| import 用的包目录 | 小写 + 下划线 (snake_case),如 my_package |
PEP 8:模块名应短、全小写;可用下划线。不要用连字符------连字符不能作为 Python 模块名。 |
| PyPI 上的发行名 | 常用 my-package(kebab-case)或 my_package |
与 import my_package 可以不同;在 pyproject.toml 里分别写 name 与包映射。 |
tests/ |
根目录下 tests/,或 src/ 旁并列 |
测试里 import mypackage 依赖你是否 editable 安装。 |
docs/、scripts/ |
小写、复数常见 | 约定俗成,不是语法要求。 |
现代配置:pyproject.toml + 可编辑安装
可编辑安装的标准做法正在统一到 PEP 517/660 ;用 pyproject.toml 声明构建后端(如 setuptools、hatchling、flit、poetry 等)。
平铺布局示例(setuptools)
toml
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "my-package"
version = "0.1.0"
description = "示例项目"
[tool.setuptools.packages.find]
where = ["."]
include = ["mypackage*"]
src/ 布局示例(setuptools)
toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "zhisaotong-agent"
version = "0.1.0"
description = "扫地机器人智能客服 Agent(RAG + Streamlit)"
readme = { file = "PROJECT_OVERVIEW.md", content-type = "text/markdown" }
requires-python = ">=3.10"
dependencies = [
"openai>=1.0.0",
"python-dotenv>=1.0.0",
"PyYAML>=6.0",
"langchain==1.2.9",
"langchain-core>=0.3.0",
"langchain-community==0.4.1",
"langchain-ollama==1.0.1",
"langchain-chroma>=0.1.0",
"langchain-text-splitters>=0.3.0",
"dashscope==1.25.11",
"chromadb==1.4.1",
"pypdf>=4.0.0",
"streamlit>=1.28.0",
]
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools]
include-package-data = true
[tool.setuptools.package-data]
zhisaotong_agent = [
"config/*.yml",
"prompts/*.txt",
"data/**/*",
]
这样 pip install -e . 会从 src 下发现 mypackage 并正确链接。
其它后端(如 Hatch、Flit)也有各自的 packages / package-dir 配置,思想相同:告诉构建系统"包代码在哪"。
和旧式 setup.py 的对比(了解即可)
以前常见:
bash
pip install -e .
会在含 setup.py 的目录里执行 setup.py develop。现在更推荐 pyproject.toml + pip install -e .(PEP 660),行为更清晰,也便于其它工具(Ruff、MyPy、CI)统一读配置。
最小可运行心智模型
- 有一个"安装根" :含
pyproject.toml(或setup.py)的目录;你在这里执行pip install -e .。 - 有一个或多个带
__init__.py的包目录(Python 3.3+ 的 namespace package 可以没有,但多数项目仍保留)。 - 包目录名 = 别人
import时用的名字(因此不要用连字符)。 - 任选平铺或
src/,库项目更倾向src/。 - 开发时 :虚拟环境里
pip install -e ".[dev]"之类可顺带装上测试、文档依赖(在pyproject.toml的 optional dependencies 里定义)。
小结
pip install -e .:从当前目录以可编辑方式安装,改代码即生效。- 结构 :根目录放元数据与配置;可分发代码 要么直接在根下
mypackage/,要么在src/mypackage/。 - 命名 :import 包名用小写与下划线;仓库/PyPI 名可以用连字符。
- 配置 :用
pyproject.toml指明包搜索路径(尤其是src/),是现代项目的默认画风。