虚拟环境要解决的问题
安装 Python,运行 pip install requests,这个包就会被装到一个全局位置。只有一个项目时,这没什么问题。到了第三个项目,麻烦就来了:
- 项目 A 需要
django==3.2,项目 B 需要django==5.0。全局只能装其中一个版本。 - 你想试试一个新库,却不想让它污染你电脑上的所有其他项目。
- 队友克隆了你的仓库,完全不知道你到底依赖了哪些包的哪些版本。
虚拟环境就是解决办法。它是一个独立的文件夹,里面有一个 Python 解释器和它自己的库安装目录。环境激活后,终端里的 python 和 pip 会指向这个文件夹,而不是系统全局的 Python。在这里安装的包就只留在这里。
用 venv 创建虚拟环境
venv 随 Python 3 一起提供,无需安装。在项目目录中运行:
python3 -m venv .venv
这会在你的代码旁边创建一个 .venv/ 文件夹。.venv 这个名字几乎是通用约定;开头的点让它在大多数目录列表中被隐藏,VS Code 等编辑器也会自动识别它。
命令完成后,这个文件夹里会有一整套 Python(几十 MB,这很正常),以及它自己的 pip。
激活环境
激活会改写你的 shell 的 PATH,让 python 和 pip 指向 .venv/ 里的那一套。具体命令取决于你的平台:
# macOS / Linux
source .venv/bin/activate
# Windows (Command Prompt)
.venv\Scripts\activate.bat
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
环境激活期间,命令提示符前会多出 (.venv) 前缀,提醒你当前所在的环境。现在运行的任何 pip install 都只影响这个项目。
一天的工作结束后,deactivate 会恢复之前的状态:
deactivate
关闭终端前不需要先退出环境:退出 shell 的效果是一样的。
安装包
在环境激活的状态下,安装你需要的包:
pip install requests
pip install "pandas>=2.0"
pip install --upgrade requests
用 pip list 查看已安装的包,用 pip uninstall requests 卸载包。
已安装的包位于 .venv/lib/pythonX.Y/site-packages/ 下。永远不要手动编辑它们,这个目录由 pip 管理。
用 requirements.txt 固定依赖
只有别人能安装和你相同的版本,你的项目才是可复现的。最简单的记录方式就是 requirements.txt:
pip freeze > requirements.txt
pip freeze 会列出每个已安装的包及其精确版本。把这个文件提交到 git。
当协作者(或者在新电脑上的你自己)克隆仓库时:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
三条命令,对方的环境就和你的一模一样了。
一个常见的项目配置流程
完整的工作流程,从头到尾:
# Create the project folder
mkdir my_tool && cd my_tool
# Create and activate the venv
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install requests rich
# Save them
pip freeze > requirements.txt
# Work on your code...
echo "import requests; print(requests.__version__)" > main.py
python main.py
# When you're done
deactivate
把 .venv 加入 .gitignore
永远不要提交 .venv/ 文件夹。它和平台相关,而且可以通过 requirements.txt 重新生成:
# .gitignore
.venv/
__pycache__/
*.pyc
提交它会让仓库变得臃肿,在别的电脑上无法使用,还会把解释器附带的操作系统专属二进制文件一并带上。
用哪个 Python 版本?
默认情况下,python3 -m venv .venv 使用的是你的 shell 找到的那个 python3。如果你装了多个 Python(比如 3.12 和 3.13),就明确指定用哪一个:
python3.13 -m venv .venv
虚拟环境一旦创建,它的解释器版本就固定了:在激活的虚拟环境中运行 python,用的永远是那个版本,即使系统的 Python 变了也一样。
出问题时怎么办
几种常见症状及解决办法:
pip install成功了,但导入失败。 你装到了错误的 Python 上。先激活虚拟环境再pip install,并用which python(macOS/Linux)或where python(Windows)重新确认。- 激活后出现“ModuleNotFoundError”。 虚拟环境创建时缺少某些库,或者包被装到了另一个虚拟环境里。
pip list会显示当前环境里实际有哪些包。 - Windows 上找不到激活脚本。 PowerShell 可能会阻止未签名的脚本。运行一次
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned,允许运行本地脚本。 - “No module named venv”。 在某些 Linux 发行版上,venv 是一个单独的包。在 Debian/Ubuntu 上运行
sudo apt install python3-venv。
venv 之外:Poetry、uv、pipenv
熟悉了 venv + pip + requirements.txt 之后,你会遇到一些工具,它们用更顺手的方式包装了同样的思路:
- Poetry:用一个
pyproject.toml管理虚拟环境、依赖和打包。 - uv:速度极快、可直接替代
pip的工具,也能管理虚拟环境。 - pipenv:较早的工具,让“Pipfile + Pipfile.lock”这种模式流行起来。
它们都很好用,但学习阶段一个都不是必需的。先熟练掌握普通的 venv 工作流程,其他的都只是优化。
要点回顾
- 每个正经的 Python 项目都要有自己的虚拟环境。
- 用
python3 -m venv .venv创建,激活之后就可以放心地pip install。 - 用
pip freeze > requirements.txt固定依赖,并提交这个文件。 - 永远不要提交
.venv/文件夹本身。 - 导入出问题时,先检查当前激活的是哪个 Python。
下一篇:__main__ 模式
项目配置好了,包也装好了,本章最后还有一个惯用写法:if __name__ == "__main__" 判断。几乎每个要作为脚本运行的 Python 文件里都有它,这也是下一篇的主题。
常见问题
Python 虚拟环境是什么?
虚拟环境是一个独立的文件夹,里面有自己的 Python 解释器,以及存放已安装库的 site-packages 目录。激活之后,python 和 pip 会指向这个文件夹,而不是系统的 Python,所以你安装的包不会在项目之间互相串。
Python 中如何创建虚拟环境?
在项目文件夹里运行 python3 -m venv .venv。这会创建一个 .venv 目录,里面是一套全新的 Python。在 macOS/Linux 上用 source .venv/bin/activate 激活,在 Windows 上用 .venv\Scripts\activate。之后 pip install 只会影响这个项目。
每个 Python 项目都应该用虚拟环境吗?
只要不是一次性脚本,都应该用。它能避免项目之间的版本冲突,让依赖在 requirements.txt(或 pyproject.toml)中一目了然,也能让协作者复现你的环境。花一分钟配置,能省下以后调试 ModuleNotFoundError 的好几个小时。
venv 和 virtualenv 有什么区别?
venv 内置于 Python 3,无需安装。virtualenv 是比它更早出现的第三方工具,多了一些功能(创建更快、支持更老的 Python 版本)。大多数现代项目默认用 venv 就对了;只有在有特定需求时才用 virtualenv。