Python 虚拟环境与依赖管理:从 venv 到 requirements 的一次讲清
刚学 Python 的时候,我习惯把所有包都装在系统自带的 Python 里。装得越多,问题来得越快:A 项目要 requests 2.x,B 项目要 requests 1.x;升级一个库,另一个项目直接跑不起来;换一台电脑,根本记不清当初装了什么、装了哪个版本。后来我才明白,问题的根不在某个具体的库,而在缺少一层隔离:每个项目都应该有自己独立的运行环境。这篇文章就把这套做法一次讲清:创建、激活、装包、冻结、复现。
一、虚拟环境到底隔离了什么
Python 的虚拟环境(venv)会在项目目录下创建一套独立的解释器入口和包安装目录。激活之后,python 和 pip 指向的都是环境内部的路径,装进来的包只对当前项目可见,系统全局环境完全不受影响。删除环境也很干净:删掉目录就是卸载,不留残留配置。
二、创建与激活:三条命令
在 Linux 或 macOS 上:
python3 -m venv .venv
source .venv/bin/activate
pip install requests
Windows 上创建命令一样,激活命令不同:
python -m venv .venv
.venv\Scripts\activate
激活成功后,终端提示符前会出现 (.venv)。这一步最容易被跳过:不激活就 pip install,包会装进全局环境,后面排查起来非常痛苦。
一个小提醒:Debian / Ubuntu 的精简系统上,python3-venv 是单独的包,没装会报 ensurepip is not available,先执行 sudo apt install -y python3-venv python3-pip 再创建。
三、requirements.txt:把依赖写下来
环境能跑起来只是第一步,能复现才是完整的工作流。把依赖写进 requirements.txt,别人拿到项目只需要三步:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
版本约束建议写得有分寸:requests==2.31.0 是精确锁定,适合要严格复现的生产项目;flask>=2.3.0 是下限约束,给升级留空间;开发阶段先用 == 锁死,跑通之后再根据需要放宽。
当前环境里装了什么,可以随时冻结下来:
pip freeze > requirements.txt
不过 pip freeze 会把所有间接依赖也列出来,文件会比较长。我的习惯是:给人看的 requirements.txt 只手写直接依赖,需要严格复现时再额外生成一份 requirements-lock.txt。
四、四个常见坑
第一,激活了却发现 pip 还是全局的。多半是没有用 source,直接执行了 activate 脚本;必须 source .venv/bin/activate,让它修改当前 shell 的环境变量。
第二,换了 Python 版本,旧环境行为异常。venv 在创建时就绑定了解释器,升级系统 Python 后旧环境可能指向不存在的路径,删掉目录重建是最省事的办法。
第三,多个项目共用一个环境。图省事只会把依赖搅在一起,版本冲突迟早出现;一个项目一个环境,是这条实践里最值得坚持的纪律。
第四,把 .venv 提交进 Git。虚拟环境目录动辄几百兆,换机器也无法直接复用,应该放进 .gitignore,只提交 requirements.txt 和代码。
五、一个推荐的日常流程
我的固定流程是:新建项目先 python3 -m venv .venv,进目录第一件事就是激活;装包后立刻 pip freeze 更新依赖文件;提交代码前检查 .gitignore 里有没有 .venv。这套流程不花哨,但它解决的是真实的工程问题:今天能跑的代码,下个月、在同事的电脑上、在服务器上,也能一样跑起来。
虚拟环境不是什么高深技术,它只是一种分工:项目归项目,环境归环境。把依赖关系显式地写下来、隔离起来,省下的排障时间,远比创建环境的那几秒钟多得多。
- 点赞
- 收藏
- 关注作者
评论(0)