用 venv 把 Python 依赖关进自己的房间
装过两次 Python 包之后,很多人会遇到同一类事故:项目 A 要某个库的旧版本,项目 B 的脚本却在新版本上报错;或者一升级系统自带的 pip,别的小工具跟着坏。虚拟环境要解决的就是这件事。它不是再装一套 Python 那么玄乎,而是给每个项目一间单独的房间:自己的第三方包目录、自己的 pip,互不踩脚。
venv 是标准库自带的,不用先装 virtualenv。在项目目录里执行:
python3 -m venv .venv
这条命令会新建一个 .venv 目录。里面有一份指向当前解释器的环境、一份独立的 pip,以及空的第三方包目录。系统里原来的包还在,但只要你走进这个环境,import 默认就不会再去翻系统目录。
走进房间的方式因系统而异。Linux 和 macOS:
source .venv/bin/activate
Windows 的命令提示符则是:
.venv\\Scripts\\activate.bat
激活之后,提示符前面通常会多出 (.venv)。这时用 which python 或 where python 看一下,路径应该落在 .venv 里面,而不是 /usr/bin/python3。这一步值得多看一眼。如果指错了,后面 pip install 装进去的包,运行时根本用不上。
装依赖时养成两个习惯。第一,始终用 python -m pip,而不是裸的 pip。前者明确绑在当前解释器上,避免 PATH 里另一个 pip 抢跑。第二,把依赖记下来:
python -m pip freeze > requirements.txt
freeze 会连同间接依赖的精确版本一起写下,适合锁定环境。如果只想记录自己声明过的顶层包,可以手写一份短清单,不必把所有传递依赖都摊开。换机器或换目录时,三行就能回到大致相同的组合:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
有几个容易忽略的点。不要把 .venv 提交进 Git,在 .gitignore 里写一行 .venv 即可,仓库里只留 requirements。解释器大版本升级之后,旧的虚拟环境经常要删掉重建,因为里面的 pip 和二进制扩展是按当时的 Python 准备的。另外,deactivate 只是退出当前 shell 的环境变量,不会删除目录;真正卸掉环境,是把 .venv 文件夹删掉。
再补两个日常会碰到的细节。一个是同一个仓库里同时存在脚本和命令行工具时,优先把入口写成 python -m 包名,而不是依赖安装后生成的控制台脚本。这样即使用户忘了激活环境,只要解释器路径是对的,行为仍然可预期。另一个是在 CI 里不要复用开发机上的 .venv。流水线每次从干净目录创建环境,再按 requirements 安装,才能发现「我本地能跑、别人拉下来不行」这种漏提交。
如果团队里有人习惯 conda,也不必互相说服。原则是一样的:依赖声明进仓库,解释器与包目录留在本机或构建机,不把装出来的目录当源码。venv 的好处只是零额外安装,适合纯 Python 小项目;遇到需要编译科学计算库时,再换更重的环境工具也不迟。
我自己会把「一项目一环境」当成默认动作,哪怕脚本只有几十行。房间小一点没关系,至少下次装包时,不会再把客厅里的公共工具一起弄坏。
最后记一条自检:激活后执行 python -c “import sys; print(sys.prefix)”。打印出来的路径如果在项目的 .venv 下,说明当前进程确实关进了自己的房间。路径若仍是系统前缀,先别装包,回到激活那一步重来。
- 点赞
- 收藏
- 关注作者
评论(0)