刚开始写Python的时候,我经常直接在系统环境里装依赖:
pip install fastapi
pip install requests对于简单的脚本来说,这完全没问题。
但电脑上的Python项目一多,问题就来了。
一个项目需要:
FastAPI 0.x另一个项目可能需要:
FastAPI 1.x如果所有项目共用一个Python环境,依赖之间很容易打架。
这就是Python虚拟环境存在的主要原因。
什么是虚拟环境
可以简单理解成:
每个Python项目都有一套独立的依赖环境。
比如:
项目A
├── Python
├── FastAPI
└── requests
项目B
├── Python
├── Django
└── numpy两个项目互不影响。
就算:
项目A → requests版本A
项目B → requests版本B也能同时存在。
venv
Python自带了venv。
比如:
python -m venv .venv项目目录下会出现:
.venv/然后激活环境。
Windows:
.venv\Scripts\Activate.ps1Linux:
source .venv/bin/activate激活之后:
python和:
pip默认都会指向这个项目自己的环境。
requirements.txt项目依赖列表
以前生成requests.txt比较常见的做法是:
pip freeze > requirements.txt然后其他机器上:
pip install -r requirements.txt就能装好所有依赖。
这种方式到现在依然很普遍。
不过我觉得requirements.txt更适合简单项目。
项目复杂了之后,依赖管理可以考虑更现代的工具(比如uv)。
别把.venv提交到Git
这是一个很重要的习惯。
.venv目录可能很大,而且里面都是可以重新装的依赖。
所以.gitignore里面必须加上(JetBrains IDE的项目新建初始化一般都帮我们做了这一步):
.venv/Git仓库只需要保存:
源代码
依赖声明
配置模板不需要保存整个Python环境(一坨venv你想把仓库当网盘用吗 doge)。
Python版本也很重要
依赖隔离只是第一步。
不同项目可能还需要不同的Python版本。
比如:
项目A → Python 3.11
项目B → Python 3.12这种情况可以用版本管理工具来解决。
我觉得Python项目真正稳定的环境至少应该明确:
Python版本
依赖版本
启动方式
环境变量这样换电脑或者部署的时候,才不会经常出现:
"我这儿怎么跑不起来?"
为什么开发环境和服务器环境经常出问题
很多Python项目在开发机上跑得好好的:
Windows
Python 3.x
各种依赖部署到Linux:
Debian
Python 3.x结果突然报错。
很多时候不是代码本身有问题,而是环境不一致。
所以一个项目最好尽量明确如下内容并写入到项目文档README.md中靠前的地方:
Python版本
依赖版本
操作系统要求
启动命令
环境变量虚拟环境不是为了"高级"
刚开始的时候我觉得:
一个Python项目直接pip install不就行了吗?
项目少的时候确实如此。
但项目一多,虚拟环境的价值就体现出来了。
它解决的是一个很基础的问题:
项目之间互不污染尤其是开发FastAPI、爬虫、自动化脚本等多个Python项目时,我现在基本都会给每个项目单独建环境。
最终形成:
project/
├── .venv/
├── src/
├── requirements.txt
└── README.md这已经是我比较习惯的Python项目结构了。
总结
虚拟环境本质上不复杂。
它只是让:项目A和项目B的依赖彼此隔开。
如果电脑上只有一个Python项目,它可能显得有点多余。
但一旦同时维护多个项目,虚拟环境几乎就成了必需品。
对我来说,现在新建一个Python项目,第一件事之一就是先把独立环境建好。