pip install -e .是以可编辑模式安装当前项目,通过创建指向源码的.pth文件或.egg-link软链接,使修改代码后立即生效,无需重新安装。

pip install -e 不是“装个包”,而是把当前项目活体接入 Python 环境——改代码、立刻生效,不用反复 pip install、卸载、重装。
它解决的核心问题是:你在本地写一个包(比如 myutils),又在另一个脚本里 import myutils,但每次改完 myutils/ 里的代码,都要重新安装才能测试?太慢,也容易漏掉 setup.py 的小错误。用 -e 就绕过打包安装流程,直接软链接进 site-packages。
什么时候必须用 pip install -e .
你正在开发一个可被他人 pip 安装的 Python 包(即含 setup.py 或 pyproject.toml),且需要满足以下任一条件:
- 在 Jupyter 或终端里频繁
import mypackage并调试逻辑 - 包内有 C 扩展或 Cython 模块,希望改完
.pyx后运行python setup.py build_ext --inplace即可 import - 多个本地包互相依赖(如
core和cli),想让它们彼此 import 时走源码路径而非已安装的 wheel - CI 流水线中跑单元测试前,要确保测试环境加载的是当前分支的最新源码,不是 PyPI 上的老版本
注意:-e 不适用于纯脚本项目(没 setup.py)或只用 __init__.py 组织的临时模块——它依赖构建后端能识别的元数据。
立即学习“Python免费学习笔记(深入)”;
pip install -e . 实际做了什么
执行该命令时,pip 会:
- 读取当前目录下的
setup.py(或现代项目的pyproject.toml中的[build-system]配置) - 调用构建后端(如
setuptools或hatchling)生成一个“可编辑安装记录”(myproject.egg-info目录或myproject-0.1.0.dist-info) - 在 Python 的
site-packages/下创建一个指向当前目录的 **pth 文件**(如myproject.egg-link),而不是复制文件 - 把当前目录加进
sys.path,所以import mypackage就等于直接导入你正在编辑的源码
你可以验证:运行 pip show mypackage,看到 Location: 指向你的项目根目录;pip list 中包名后带 (editable) 标记。
常见报错和坑点
这些错误往往不是 pip 本身的问题,而是项目配置或环境状态导致的:
-
ERROR: File "setup.py" not found:当前目录没有setup.py,且pyproject.toml里没声明构建系统。补一个最简setup.py或按 PEP 517 补全pyproject.toml -
ModuleNotFoundError: No module named 'mypackage':虽然pip install -e .成功了,但你用的是另一个 Python 解释器(比如 VS Code 默认启用了 conda 环境,而你在 base 里装的)。检查which python和pip --version是否一致 -
改了
setup.py里的packages却不生效:-e模式不会自动重读setup.py。必须重新运行pip install -e .才会更新.egg-info和导入路径 -
Windows 下路径含空格或中文时报错:尽量把项目放在
C:\dev\这类纯英文无空格路径下,避免构建工具解析失败
另外,-e 安装的包不会出现在 pip freeze > requirements.txt 的输出里(因为不是 wheel 安装),如果要导出可复现的依赖,得手动加上 -e file:///abs/path/to/mypackage 这类行。
替代方案与边界情况
不是所有场景都适合 -e:
- 如果你只是临时写几个函数,没打算发布成包,直接把模块所在目录加到
PYTHONPATH更轻量:export PYTHONPATH=$(pwd):$PYTHONPATH - 使用
conda develop .(来自 conda-build)也能实现类似效果,但要求环境是 conda 管理,且需提前conda install conda-build -
pip install -e .[dev]可以同时安装extras_require里定义的开发依赖(如pytest),但前提是setup.py或pyproject.toml正确声明了dev分组
真正容易被忽略的一点:当你在 IDE(如 PyCharm)里启用 -e 模式后,它的代码跳转、类型提示、自动补全会直接指向你本地的源码文件——这既是优势,也是责任:你得确保 __init__.py 导出正确,否则整个 IDE 的智能提示就断了。


















