虚拟环境
Python 应用程序通常依赖标准库之外的第三方包,不同项目对包的版本要求可能冲突。虚拟环境通过创建一个隔离的目录树,在其中安装独立的 Python 解释器副本和专属包,让每个项目拥有独立的依赖空间,互不干扰。
venv 模块:创建虚拟环境
venv 是 Python 3.3+ 内置的虚拟环境管理模块,无需额外安装。它会复制当前运行的 Python 版本到目标目录:
# 创建名为 .venv 的虚拟环境(. 前缀使其在终端中默认隐藏)
python -m venv .venv
# 指定特定 Python 版本创建环境(需该版本已安装)
python3.12 -m venv project_env
# 创建时排除 pip(极简环境,需手动安装包时慎用)
python -m venv no_pip_env --without-pip
# 创建时继承系统 site-packages(减少重复安装)
python -m venv shared_env --system-site-packages
创建后的目录结构如下:
.venv/
├── pyvenv.cfg # 环境配置,记录基础解释器路径和版本
├── Scripts/ # Windows 可执行文件目录
│ ├── activate.bat # cmd 激活脚本
│ ├── Activate.ps1 # PowerShell 激活脚本
│ ├── python.exe # 当前环境的 Python 解释器
│ └── pip.exe # 当前环境的 pip
├── Lib/
│ └── site-packages/ # 第三方包安装位置
└── include/ # C 扩展头文件
pyvenv.cfg 的内容示例:
home = C:\Users\AOXIANG\AppData\Local\Programs\Python\Python312
include-system-site-packages = false
version = 3.12.4
executable = C:\Users\AOXIANG\AppData\Local\Programs\Python\Python312\python.exe
command = C:\Users\AOXIANG\AppData\Local\Programs\Python\Python312\python.exe -m venv .venv
激活与退出
激活虚拟环境会修改当前终端的 PATH 环境变量,使 python 和 pip 命令指向虚拟环境内的副本,同时修改命令行提示符前缀:
# Windows (cmd)
.venv\Scripts\activate.bat
# Windows (PowerShell) —— 可能需要先执行 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
.venv\Scripts\Activate.ps1
# macOS / Linux (bash/zsh)
source .venv/bin/activate
# 使用 fish shell
source .venv/bin/activate.fish
激活后提示符变化:
$ source .venv/bin/activate
(.venv) $ python -c "import sys; print(sys.executable)"
/home/user/project/.venv/bin/python
(.venv) $ pip --version
pip 24.0 from .../site-packages/pip (python 3.12)
退出虚拟环境只需执行 deactivate,这会恢复原来的 PATH 和提示符:
(.venv) $ deactivate
$ python -c "import sys; print(sys.executable)"
/usr/bin/python3 # 恢复系统 Python
注意:虚拟环境不是容器,它只隔离 Python 包,不隔离系统资源。激活脚本仅在当前终端会话生效,新开终端需要重新激活。
pip 包管理
pip 是 Python 的包安装程序,默认从 PyPI(Python Package Index)下载包。在虚拟环境中使用 python -m pip 是推荐做法,确保调用的是当前环境的 pip:
# 安装最新版本
python -m pip install requests
# 安装指定版本(精确控制依赖)
python -m pip install requests==2.31.0
# 安装最低版本要求
python -m pip install "requests>=2.30.0"
# 升级包
python -m pip install --upgrade requests
# 卸载包
python -m pip uninstall requests
# 显示包详情
python -m pip show requests
# 列出已安装包
python -m pip list
# 检查哪些包有更新
python -m pip list --outdated
pip show 的输出包含名称、版本、摘要、主页、作者、许可证和安装位置,是排查依赖问题时的重要工具:
Name: requests
Version: 2.31.0
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
License: Apache 2.0
Location: /home/user/project/.venv/lib/python3.12/site-packages
Requires: charset-normalizer, idna, urllib3, certifi
requirements.txt 与依赖锁定
pip freeze 以 包名==版本 的格式输出当前环境的所有已安装包,常用于生成 requirements.txt:
python -m pip freeze > requirements.txt
生成的文件示例:
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.6
requests==2.31.0
urllib3==2.2.1
新环境或同事可以通过 -r 参数一键复现:
python -m pip install -r requirements.txt
生产环境建议区分 requirements.txt(生产依赖)和 requirements-dev.txt(开发依赖,包含测试、格式化工具):
# 开发依赖文件示例
-r requirements.txt
pytest==8.0.0
black==24.1.0
mypy==1.8.0
pip freeze 会包含所有子依赖,有时过于冗长。另一种做法是手写 requirements.in 只列出顶层依赖,再用 pip-compile(来自 pip-tools)生成精确的锁定文件。
pyproject.toml 现代项目配置
pyproject.toml 是 PEP 518 引入的统一项目配置文件,取代分散的 setup.py、setup.cfg、requirements.txt 和工具配置。它使用 TOML 格式,人类可读且结构清晰:
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "feixiang-hr"
version = "1.0.0"
description = "广州飞翔科技员工管理系统"
readme = "README.md"
requires-python = ">=3.12"
license = {text = "MIT"}
authors = [
{name = "技术部", email = "tech@feixiang.com"}
]
keywords = ["hr", "employee", "management"]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"requests>=2.31.0",
"pandas>=2.1.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.4.0",
"black>=23.0",
"mypy>=1.7.0",
]
docs = [
"sphinx>=7.0",
]
[project.scripts]
hr-cli = "feixiang_hr.cli:main"
[tool.black]
line-length = 88
target-version = ['py312']
[tool.mypy]
python_version = "3.12"
strict = true
[build-system] 声明构建项目所需的工具和版本;[project] 描述项目元数据和依赖;[project.optional-dependencies] 定义可选依赖组(安装时用 pip install ".[dev]");[tool.*] 为各种工具提供统一配置入口。
与 setup.py 相比,pyproject.toml 的优势在于声明式配置(无需执行 Python 代码即可解析)、工具统一(black、mypy、pytest 等都可以从中读取配置)以及构建隔离(构建时自动创建隔离环境安装构建依赖)。
虚拟环境最佳实践
- 目录命名:优先使用
.venv,它既隐藏又避免与.env环境变量文件冲突。 - 版本控制:虚拟环境目录必须加入
.gitignore,不应提交到仓库。 - 依赖声明:始终维护
requirements.txt或pyproject.toml,确保环境可复现。 - 不要混用全局 pip:激活虚拟环境后再安装包,避免污染系统 Python。
- 定期清理:使用
python -m pip uninstall移除不再需要的包,减少环境体积。