用pip install -e .开发Python包时,Python项目目录结构(项目结构)(可编辑安装editable install)

文章目录

  • [用 `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 + 可编辑安装)
    • [和旧式 `setup.py` 的对比(了解即可)](#和旧式 setup.py 的对比(了解即可))
    • 最小可运行心智模型
    • 小结

pip install -e . 开发时,Python 项目一般长什么样?

可编辑安装在干什么?

pip install -e . 里的 -e 表示 editable install(可编辑安装) :不会把代码复制进 site-packages,而是在那里放一个指向你项目根目录的链接(或等价机制)。你改源码后,不用反复重装 ,已安装的包就会用到最新代码。适合库、框架和需要被其它项目 import 的包。

💡 举个栗子🌰 你正在开发一个工具包 my_tool:

  1. 在 my_tool 项目根目录运行 pip install -e .
  2. 另一个项目 app.py 里写 import my_tool
  3. 你修改了 my_tool 的源码 → 保存后,app.py 下次运行直接生效! (不用反复 pip uninstall + pip install,调试效率飙升✨)

要点:"点" . 表示当前目录 ;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 的关系)

类型 习惯 说明
项目根目录 myprojectdjangorequests 仓库名可与 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 声明构建后端(如 setuptoolshatchlingflitpoetry 等)。

平铺布局示例(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)统一读配置。


最小可运行心智模型

  1. 有一个"安装根" :含 pyproject.toml(或 setup.py)的目录;你在这里执行 pip install -e .
  2. 有一个或多个带 __init__.py 的包目录(Python 3.3+ 的 namespace package 可以没有,但多数项目仍保留)。
  3. 包目录名 = 别人 import 时用的名字(因此不要用连字符)。
  4. 任选平铺或 src/ ,库项目更倾向 src/
  5. 开发时 :虚拟环境里 pip install -e ".[dev]" 之类可顺带装上测试、文档依赖(在 pyproject.toml 的 optional dependencies 里定义)。

小结

  • pip install -e .:从当前目录以可编辑方式安装,改代码即生效。
  • 结构 :根目录放元数据与配置;可分发代码 要么直接在根下 mypackage/,要么在 src/mypackage/
  • 命名import 包名用小写与下划线;仓库/PyPI 名可以用连字符。
  • 配置 :用 pyproject.toml 指明包搜索路径(尤其是 src/),是现代项目的默认画风。
相关推荐
Thomas.Sir2 小时前
第三章:Python3 之 字符串
开发语言·python·字符串·string
威联通网络存储3 小时前
告别掉帧与素材损毁:威联通 QuTS hero 如何重塑影视后期协同工作流
前端·网络·人工智能·python
Dxy12393102163 小时前
Python 根据列表中某字段排序:从基础到进阶
开发语言·windows·python
splage3 小时前
Java进阶——IO 流
java·开发语言·python
cliffordl3 小时前
设计模式(python)
python·设计模式
always_TT4 小时前
从Python_Java转学C语言需要注意什么?
java·c语言·python
2301_793804694 小时前
定时任务专家:Python Schedule库使用指南
jvm·数据库·python
穿越世纪的风尘5 小时前
【问题解决】No module named ‘_sqlite3‘
python·centos
qq_416018725 小时前
用Python批量处理Excel和CSV文件
jvm·数据库·python