feat(python进阶): 完成第三至第八课教学内容
This commit is contained in:
410
02_python进阶/2_8_虚拟环境与依赖管理/README.md
Normal file
410
02_python进阶/2_8_虚拟环境与依赖管理/README.md
Normal file
@@ -0,0 +1,410 @@
|
||||
# 第 2-8 课:虚拟环境与依赖管理
|
||||
|
||||
## 一、本课目标
|
||||
|
||||
完成本课后,你将能够:
|
||||
|
||||
1. 解释虚拟环境是什么,以及为什么需要它;
|
||||
2. 在 Windows PowerShell 中创建、激活和退出虚拟环境;
|
||||
3. 确认命令实际使用的是哪个 Python 解释器;
|
||||
4. 使用 `python -m pip` 查看、安装和卸载第三方依赖;
|
||||
5. 使用 `requirements.txt` 记录与恢复项目依赖;
|
||||
6. 理解版本固定的基本作用;
|
||||
7. 知道 `.venv` 不应提交到 Git。
|
||||
|
||||
## 二、前置知识
|
||||
|
||||
学习本课前,需要掌握:
|
||||
|
||||
- 在 PowerShell 中进入目录并运行 Python 文件;
|
||||
- 模块与导入;
|
||||
- 文件和路径;
|
||||
- 基础异常处理;
|
||||
- 类型注解。
|
||||
|
||||
## 三、什么是第三方依赖
|
||||
|
||||
Python 自带的模块组成标准库(Standard Library),例如 `pathlib`、`sys` 和 `platform`,使用它们通常不需要安装额外内容。
|
||||
|
||||
第三方依赖(Third-Party Dependency)是其他开发者发布、项目需要额外安装的软件包。例如以后 Web 阶段会使用 FastAPI、Django 等框架。
|
||||
|
||||
安装依赖后,我们可以在代码中导入它:
|
||||
|
||||
```python
|
||||
import package_name
|
||||
```
|
||||
|
||||
这里的 `package_name` 只是格式示例,不要求本课安装这个不存在的软件包。
|
||||
|
||||
## 四、为什么不能把所有依赖都装在同一个环境
|
||||
|
||||
假设有两个项目:
|
||||
|
||||
- 项目 A 需要某个软件包的旧版本;
|
||||
- 项目 B 需要同一个软件包的新版本。
|
||||
|
||||
如果两个项目共用一个 Python 环境,升级项目 B 的依赖可能导致项目 A 无法运行。
|
||||
|
||||
还可能遇到:
|
||||
|
||||
- 不知道某个依赖属于哪个项目;
|
||||
- 删除一个依赖时误伤其他项目;
|
||||
- 自己的机器能运行,换一台机器却缺少依赖;
|
||||
- 项目依赖越来越杂乱。
|
||||
|
||||
## 五、什么是虚拟环境
|
||||
|
||||
虚拟环境(Virtual Environment)是为一个项目准备的独立 Python 运行环境。它拥有自己的 Python 入口和依赖安装位置。
|
||||
|
||||
可以把它理解为每个项目自己的“工具箱”:
|
||||
|
||||
```text
|
||||
项目 A → 自己的虚拟环境 → 自己的依赖
|
||||
项目 B → 自己的虚拟环境 → 自己的依赖
|
||||
```
|
||||
|
||||
虚拟环境不会复制整个操作系统,也不会删除系统 Python。它只是隔离 Python 解释器入口和软件包目录。
|
||||
|
||||
## 六、创建虚拟环境
|
||||
|
||||
本项目统一把虚拟环境放在项目根目录的 `.venv` 中。
|
||||
|
||||
先在 PowerShell 进入项目根目录:
|
||||
|
||||
```powershell
|
||||
cd D:\Code\Python
|
||||
```
|
||||
|
||||
创建环境:
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
```
|
||||
|
||||
逐段理解:
|
||||
|
||||
- `python`:使用当前 Python;
|
||||
- `-m venv`:运行标准库中的 `venv` 模块;
|
||||
- `.venv`:创建的环境目录名称。
|
||||
|
||||
创建可能需要几秒钟。成功后根目录会出现 `.venv`,但项目根目录的 `.gitignore` 已忽略它。
|
||||
|
||||
## 七、激活虚拟环境
|
||||
|
||||
PowerShell 中执行:
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
激活后,命令提示符前通常会出现:
|
||||
|
||||
```text
|
||||
(.venv)
|
||||
```
|
||||
|
||||
激活的作用主要是临时调整当前终端的命令查找顺序,让 `python` 和 `pip` 优先指向 `.venv`。
|
||||
|
||||
激活只影响当前终端窗口。关闭终端后,下次需要重新激活。
|
||||
|
||||
## 八、遇到 PowerShell 脚本限制怎么办
|
||||
|
||||
部分机器可能阻止运行 `Activate.ps1`。本课不要求为了激活环境而修改整台电脑的执行策略。
|
||||
|
||||
即使不激活,也可以直接使用虚拟环境中的 Python:
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\python.exe --version
|
||||
.\.venv\Scripts\python.exe .\02_python进阶\2_8_虚拟环境与依赖管理\environment_example.py
|
||||
```
|
||||
|
||||
这种写法目标明确,也能保证使用 `.venv`。如果遇到执行策略错误,保留英文错误原文,再说明你执行的命令,我会帮助判断。
|
||||
|
||||
## 九、确认正在使用哪个 Python
|
||||
|
||||
激活前后都可以执行:
|
||||
|
||||
```powershell
|
||||
python -c "import sys; print(sys.executable)"
|
||||
```
|
||||
|
||||
激活虚拟环境后,输出路径应指向项目中的 `.venv\Scripts\python.exe`。
|
||||
|
||||
还可以执行本课示例:
|
||||
|
||||
```powershell
|
||||
python .\02_python进阶\2_8_虚拟环境与依赖管理\environment_example.py
|
||||
```
|
||||
|
||||
示例通过比较:
|
||||
|
||||
```python
|
||||
sys.prefix != sys.base_prefix
|
||||
```
|
||||
|
||||
判断当前是否处于普通 `venv` 虚拟环境。
|
||||
|
||||
## 十、退出虚拟环境
|
||||
|
||||
激活后执行:
|
||||
|
||||
```powershell
|
||||
deactivate
|
||||
```
|
||||
|
||||
退出只会恢复当前终端的命令环境,不会删除 `.venv`。
|
||||
|
||||
以后重新使用时再次运行激活命令即可。
|
||||
|
||||
## 十一、什么是 `pip`
|
||||
|
||||
`pip` 是 Python 常用的软件包安装工具。它可以从软件包仓库下载和管理第三方依赖。
|
||||
|
||||
本课推荐始终使用:
|
||||
|
||||
```powershell
|
||||
python -m pip 命令
|
||||
```
|
||||
|
||||
而不是只写:
|
||||
|
||||
```powershell
|
||||
pip 命令
|
||||
```
|
||||
|
||||
`python -m pip` 能更明确地表示:“使用当前这个 Python 对应的 pip”,减少多个 Python 环境之间装错位置的风险。
|
||||
|
||||
## 十二、查看依赖
|
||||
|
||||
查看 pip 版本和安装位置:
|
||||
|
||||
```powershell
|
||||
python -m pip --version
|
||||
```
|
||||
|
||||
查看当前环境已安装的软件包:
|
||||
|
||||
```powershell
|
||||
python -m pip list
|
||||
```
|
||||
|
||||
查看某个已安装软件包的信息:
|
||||
|
||||
```powershell
|
||||
python -m pip show 软件包名称
|
||||
```
|
||||
|
||||
检查已安装依赖之间是否存在已知的不兼容:
|
||||
|
||||
```powershell
|
||||
python -m pip check
|
||||
```
|
||||
|
||||
## 十三、安装与卸载依赖
|
||||
|
||||
安装命令格式:
|
||||
|
||||
```powershell
|
||||
python -m pip install 软件包名称
|
||||
```
|
||||
|
||||
安装指定版本:
|
||||
|
||||
```powershell
|
||||
python -m pip install 软件包名称==版本号
|
||||
```
|
||||
|
||||
卸载:
|
||||
|
||||
```powershell
|
||||
python -m pip uninstall 软件包名称
|
||||
```
|
||||
|
||||
安装和卸载会修改当前 Python 环境。执行前必须先确认解释器路径,避免改动错误环境。本课不强制安装任何第三方依赖,也不要把示例中的占位名称原样执行。
|
||||
|
||||
## 十四、什么是版本固定
|
||||
|
||||
版本固定(Version Pinning)表示明确记录项目使用的依赖版本:
|
||||
|
||||
```text
|
||||
some-package==1.2.3
|
||||
```
|
||||
|
||||
它可以减少不同机器安装到不同版本而产生的差异。
|
||||
|
||||
需要注意:版本号必须来自项目实际验证过的环境,不要随意照抄教程中的旧版本。以后开始 FastAPI、Django 项目时,会根据实际环境选择并验证版本。
|
||||
|
||||
## 十五、使用 `requirements.txt`
|
||||
|
||||
`requirements.txt` 是常见的依赖清单文件,每行记录一个直接依赖或带版本的依赖:
|
||||
|
||||
```text
|
||||
package-a==1.2.3
|
||||
package-b==4.5.6
|
||||
```
|
||||
|
||||
在另一台机器或新虚拟环境中恢复依赖:
|
||||
|
||||
```powershell
|
||||
python -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
根据当前环境导出所有已安装包:
|
||||
|
||||
```powershell
|
||||
python -m pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
`pip freeze` 会记录当前环境中的全部软件包,包括间接依赖。导出前要确认环境干净、确实属于当前项目,避免把无关包写入清单。
|
||||
|
||||
本课没有第三方依赖,因此不会提前创建包含虚假依赖的 `requirements.txt`。
|
||||
|
||||
## 十六、不要提交 `.venv`
|
||||
|
||||
`.venv` 可能包含大量文件,并带有当前机器的路径和平台信息,不适合提交到 Git。
|
||||
|
||||
应该提交的是:
|
||||
|
||||
- Python 源代码;
|
||||
- 课程文档;
|
||||
- 经过确认的依赖清单。
|
||||
|
||||
不应该提交的是:
|
||||
|
||||
- `.venv/`;
|
||||
- `__pycache__/`;
|
||||
- 本地密钥和 `.env`。
|
||||
|
||||
本项目根目录 `.gitignore` 已包含:
|
||||
|
||||
```text
|
||||
.venv/
|
||||
venv/
|
||||
```
|
||||
|
||||
## 十七、完整示例
|
||||
|
||||
示例文件:
|
||||
|
||||
```text
|
||||
02_python进阶/2_8_虚拟环境与依赖管理/environment_example.py
|
||||
```
|
||||
|
||||
它只读取并输出:
|
||||
|
||||
- Python 版本;
|
||||
- 当前解释器路径;
|
||||
- 当前环境目录名称;
|
||||
- 是否为普通 `venv` 虚拟环境;
|
||||
- 当前环境的 pip 版本。
|
||||
|
||||
示例不会创建环境,也不会安装或卸载依赖。
|
||||
|
||||
## 十八、运行方法
|
||||
|
||||
未激活虚拟环境时运行:
|
||||
|
||||
```powershell
|
||||
python .\02_python进阶\2_8_虚拟环境与依赖管理\environment_example.py
|
||||
```
|
||||
|
||||
创建环境后,不激活而直接运行:
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\python.exe .\02_python进阶\2_8_虚拟环境与依赖管理\environment_example.py
|
||||
```
|
||||
|
||||
完成代码练习后运行:
|
||||
|
||||
```powershell
|
||||
python .\02_python进阶\2_8_虚拟环境与依赖管理\practice.py
|
||||
```
|
||||
|
||||
## 十九、预期结果
|
||||
|
||||
具体路径和版本因机器而异,格式类似:
|
||||
|
||||
```text
|
||||
Python 版本:3.x.x
|
||||
Python 解释器:某个实际路径
|
||||
当前环境目录:某个环境名称
|
||||
是否为 venv 虚拟环境:是或否
|
||||
pip 版本:某个实际版本
|
||||
```
|
||||
|
||||
在普通环境中通常显示“否”;使用 `.venv\Scripts\python.exe` 运行时应显示“是”。
|
||||
|
||||
## 二十、常见错误
|
||||
|
||||
### 20.1 创建环境后仍然使用原 Python
|
||||
|
||||
创建 `.venv` 不等于已经切换环境。需要激活,或者直接调用 `.venv\Scripts\python.exe`。
|
||||
|
||||
### 20.2 把依赖安装到错误环境
|
||||
|
||||
安装前先执行:
|
||||
|
||||
```powershell
|
||||
python -c "import sys; print(sys.executable)"
|
||||
```
|
||||
|
||||
确认路径后再使用 `python -m pip install`。
|
||||
|
||||
### 20.3 把 `.venv` 提交到 Git
|
||||
|
||||
虚拟环境是本地生成内容,应由 `.gitignore` 忽略。其他机器根据依赖清单重新创建。
|
||||
|
||||
### 20.4 把依赖清单当成虚拟环境
|
||||
|
||||
`requirements.txt` 只记录依赖名称和版本,不包含已安装文件。仍需先创建环境,再安装清单。
|
||||
|
||||
### 20.5 认为激活会永久改变系统
|
||||
|
||||
激活主要影响当前终端。执行 `deactivate` 或关闭终端即可退出。
|
||||
|
||||
### 20.6 随意修改 PowerShell 执行策略
|
||||
|
||||
激活脚本被阻止时,可以直接使用 `.venv\Scripts\python.exe`,本课不要求修改系统级策略。
|
||||
|
||||
## 二十一、课堂练习
|
||||
|
||||
练习分为两部分。
|
||||
|
||||
终端操作:
|
||||
|
||||
1. 在普通环境运行 `environment_example.py` 并记录结果;
|
||||
2. 在项目根目录创建 `.venv`;
|
||||
3. 激活环境,或直接使用 `.venv\Scripts\python.exe`;
|
||||
4. 再次运行示例并比较解释器路径;
|
||||
5. 执行 `python -m pip --version` 和 `python -m pip list`;
|
||||
6. 退出环境并确认解释器恢复。
|
||||
|
||||
代码练习:打开 `practice.py`,完成环境判断、版本读取、环境报告和输出函数。
|
||||
|
||||
## 二十二、参考答案
|
||||
|
||||
参考答案暂不写入练习文件。完成后,我会验证函数行为和类型注解,并分别在当前解释器与临时虚拟环境中运行,确认环境判断能够反映真实差异。
|
||||
|
||||
## 二十三、本课小结
|
||||
|
||||
- 虚拟环境为项目隔离 Python 解释器入口和依赖;
|
||||
- 使用 `python -m venv .venv` 创建环境;
|
||||
- 激活后,当前终端优先使用虚拟环境;
|
||||
- 不激活时也可以直接调用虚拟环境中的 Python;
|
||||
- `python -m pip` 能减少把依赖装错环境的风险;
|
||||
- `requirements.txt` 用于记录和恢复依赖;
|
||||
- 版本固定有助于保持不同机器的环境一致;
|
||||
- `.venv` 是本地生成目录,不应提交到 Git。
|
||||
|
||||
## 二十四、验收标准
|
||||
|
||||
- 能解释虚拟环境解决的问题;
|
||||
- 能创建、进入和退出 `.venv`;
|
||||
- 能确认当前 Python 解释器路径;
|
||||
- 能使用 `python -m pip` 查看依赖;
|
||||
- 能说明安装与卸载会修改当前环境;
|
||||
- 能解释 `requirements.txt` 的用途;
|
||||
- 能说明版本固定的基本作用;
|
||||
- 能解释为什么 `.venv` 不应提交;
|
||||
- 环境检查脚本在普通环境与 `.venv` 中显示不同判断;
|
||||
- 没有把个人绝对路径或虚假依赖写入项目文件。
|
||||
45
02_python进阶/2_8_虚拟环境与依赖管理/environment_example.py
Normal file
45
02_python进阶/2_8_虚拟环境与依赖管理/environment_example.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# 第 2-8 课完整示例:虚拟环境与依赖管理
|
||||
#
|
||||
# 本示例只读取当前 Python 解释器和环境信息,不安装、卸载任何依赖。
|
||||
|
||||
import platform
|
||||
import sys
|
||||
from importlib.metadata import PackageNotFoundError, version
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def is_virtual_environment() -> bool:
|
||||
"""判断当前程序是否运行在普通 venv 虚拟环境中。"""
|
||||
# 普通环境中 sys.prefix 和 sys.base_prefix 通常相同。
|
||||
# venv 激活并使用其 Python 后,这两个路径通常不同。
|
||||
return sys.prefix != sys.base_prefix
|
||||
|
||||
|
||||
def get_package_version(package_name: str) -> str | None:
|
||||
"""返回已安装依赖的版本,未安装时返回 None。"""
|
||||
try:
|
||||
return version(package_name)
|
||||
except PackageNotFoundError:
|
||||
return None
|
||||
|
||||
|
||||
def get_environment_name() -> str:
|
||||
"""返回当前环境目录名称。"""
|
||||
return Path(sys.prefix).name
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""输出解释器、虚拟环境和 pip 版本信息。"""
|
||||
in_virtual_environment = is_virtual_environment()
|
||||
environment_status = "是" if in_virtual_environment else "否"
|
||||
pip_version = get_package_version("pip")
|
||||
|
||||
print(f"Python 版本:{platform.python_version()}")
|
||||
print(f"Python 解释器:{sys.executable}")
|
||||
print(f"当前环境目录:{get_environment_name()}")
|
||||
print(f"是否为 venv 虚拟环境:{environment_status}")
|
||||
print(f"pip 版本:{pip_version}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
78
02_python进阶/2_8_虚拟环境与依赖管理/practice.py
Normal file
78
02_python进阶/2_8_虚拟环境与依赖管理/practice.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# 第 2-8 课课堂练习:检查虚拟环境
|
||||
#
|
||||
# 本文件只读取环境信息,不负责创建环境或安装依赖。
|
||||
# 创建、激活和退出虚拟环境的操作请按照讲义在 PowerShell 中完成。
|
||||
# 不要删除题目、预期结果和自查注释。
|
||||
|
||||
# 第一部分:定义 is_virtual_environment() 函数
|
||||
# 1. 不接收参数,返回值标注为 bool。
|
||||
# 2. 比较 sys.prefix 和 sys.base_prefix。
|
||||
# 3. 两者不相等时返回 True,否则返回 False。
|
||||
# 4. 不要根据路径中是否包含“.venv”来判断。
|
||||
|
||||
# 第二部分:定义 get_python_version() 函数
|
||||
# 1. 不接收参数,返回值标注为 str。
|
||||
# 2. 调用 platform.python_version() 并 return 结果。
|
||||
# 3. 不要手工写死版本号,因为不同机器的版本可能不同。
|
||||
|
||||
# 第三部分:定义 get_environment_name() 函数
|
||||
# 1. 不接收参数,返回值标注为 str。
|
||||
# 2. 使用 Path(sys.prefix).name 取得当前环境目录名称。
|
||||
# 3. return 得到的名称。
|
||||
|
||||
|
||||
|
||||
# 第四部分:定义 get_environment_report() 函数
|
||||
# 1. 不接收参数,返回值标注为 dict[str, str]。
|
||||
# 2. 调用前面三个函数。
|
||||
# 3. 把布尔值转换为中文:“是”或“否”。
|
||||
# 4. return 包含以下三个键的字典:
|
||||
# "python_version":当前 Python 版本;
|
||||
# "environment_name":当前环境目录名称;
|
||||
# "is_virtual_environment":中文“是”或“否”。
|
||||
|
||||
|
||||
# 第五部分:定义 print_environment_report(report) 函数
|
||||
# 1. 参数标注为 dict[str, str],返回值标注为 None。
|
||||
# 2. 依次输出:
|
||||
# Python 版本:实际版本
|
||||
# 当前环境:实际环境名称
|
||||
# 是否为虚拟环境:是或否
|
||||
# 3. 本函数只负责输出,不修改 report。
|
||||
|
||||
|
||||
# 第六部分:定义 main() 函数
|
||||
# 1. 返回值标注为 None。
|
||||
# 2. 调用 get_environment_report() 并保存结果。
|
||||
# 3. 调用 print_environment_report() 输出报告。
|
||||
# 4. 添加程序入口判断,直接运行本文件时调用 main()。
|
||||
|
||||
|
||||
# 第七部分:在两个环境中运行
|
||||
# 1. 未激活本课虚拟环境时运行一次 practice.py,记录输出。
|
||||
# 2. 按讲义创建并激活项目根目录下的 .venv。
|
||||
# 3. 再次运行 practice.py。
|
||||
# 4. 对比两次的环境名称和“是否为虚拟环境”。
|
||||
# 5. 两台机器的路径和 Python 版本可能不同,不要求写死相同结果。
|
||||
|
||||
|
||||
# 最终验收测试:
|
||||
# 1. 所有函数的参数和返回值注解正确;
|
||||
# 2. Python 版本来自 platform.python_version();
|
||||
# 3. 环境名称来自 Path(sys.prefix).name;
|
||||
# 4. 虚拟环境判断来自 sys.prefix != sys.base_prefix;
|
||||
# 5. 报告字典包含三个指定键,值都是字符串;
|
||||
# 6. 输出函数不修改报告字典;
|
||||
# 7. 普通环境与 .venv 中的输出能够体现环境差异;
|
||||
# 8. 没有在代码中写死个人机器路径或 Python 版本;
|
||||
# 9. 没有在脚本中自动安装或卸载依赖。
|
||||
|
||||
|
||||
# 完成后自查:
|
||||
# 1. 是否知道虚拟环境用于隔离项目依赖;
|
||||
# 2. 是否知道激活环境不会删除系统 Python;
|
||||
# 3. 是否优先使用 python -m pip;
|
||||
# 4. 是否知道 requirements.txt 用于记录项目依赖;
|
||||
# 5. 是否知道 .venv 不应提交到 Git;
|
||||
# 6. 是否能退出环境并重新激活;
|
||||
# 7. 是否保留了完整题目和验收说明。
|
||||
405
02_python进阶/2_8_虚拟环境与依赖管理/补充_conda_pip_uv与虚拟环境的区别.md
Normal file
405
02_python进阶/2_8_虚拟环境与依赖管理/补充_conda_pip_uv与虚拟环境的区别.md
Normal file
@@ -0,0 +1,405 @@
|
||||
# 补充:Conda、pip、uv 与 Python 虚拟环境的区别
|
||||
|
||||
## 一、先给出结论
|
||||
|
||||
这些名称不完全属于同一类工具:
|
||||
|
||||
- `venv`、`virtualenv`:主要负责创建相互隔离的 Python 环境;
|
||||
- `pip`:主要负责向某个 Python 环境安装和卸载 Python 软件包,本身不负责创建虚拟环境;
|
||||
- Conda:同时管理环境、Python 版本、Python 包和部分非 Python 软件;
|
||||
- `uv`:同时覆盖 Python 版本、虚拟环境、依赖安装、项目依赖和锁文件等工作。
|
||||
|
||||
因此,“Conda、pip、uv 哪个虚拟环境更好”这个问题并不完全准确。更合适的问题是:
|
||||
|
||||
> 当前项目应该使用哪一种环境管理与依赖管理组合?
|
||||
|
||||
## 二、几个概念不要混在一起
|
||||
|
||||
### 2.1 Python 解释器
|
||||
|
||||
Python 解释器是实际运行 `.py` 文件的程序,例如当前机器检测到的:
|
||||
|
||||
```text
|
||||
C:\ProgramData\miniconda3\python.exe
|
||||
```
|
||||
|
||||
不同环境可能有自己的解释器入口,也可能使用不同的 Python 版本。
|
||||
|
||||
### 2.2 虚拟环境
|
||||
|
||||
虚拟环境负责隔离项目使用的 Python 和已安装软件包。例如项目 A 与项目 B 可以分别拥有自己的 `.venv`,互不影响。
|
||||
|
||||
### 2.3 包管理器
|
||||
|
||||
包管理器负责查找、安装、更新和卸载软件包:
|
||||
|
||||
- `pip` 主要管理 Python 软件包;
|
||||
- Conda 可以管理 Conda 软件包,其中可以包含 Python、Python 包以及其他软件;
|
||||
- `uv` 可以通过项目工作流或兼容 pip 的命令管理 Python 依赖。
|
||||
|
||||
### 2.4 依赖解析与锁定
|
||||
|
||||
依赖解析负责计算“安装哪些版本才能彼此兼容”。锁文件用于记录解析后的精确结果,使其他机器尽量复现相同环境。
|
||||
|
||||
常见文件包括:
|
||||
|
||||
- pip 工作流:`requirements.txt`;
|
||||
- Conda 工作流:`environment.yml`,也可配合相应锁文件;
|
||||
- uv 项目工作流:`pyproject.toml` 和 `uv.lock`。
|
||||
|
||||
## 三、`venv`:Python 自带的基础选择
|
||||
|
||||
`venv` 是 Python 标准库中的虚拟环境工具,不需要单独安装。
|
||||
|
||||
创建环境:
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
```
|
||||
|
||||
激活:
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
在环境中安装包:
|
||||
|
||||
```powershell
|
||||
python -m pip install 软件包名称
|
||||
```
|
||||
|
||||
特点:
|
||||
|
||||
- Python 自带,概念简单;
|
||||
- 通常基于创建它的现有 Python;
|
||||
- 只负责创建环境,不负责完整项目锁定;
|
||||
- 通常与 `pip`、`requirements.txt` 一起使用;
|
||||
- 适合普通 Python 脚本、Web 后端和入门学习。
|
||||
|
||||
典型组合:
|
||||
|
||||
```text
|
||||
venv 创建环境
|
||||
+ pip 安装依赖
|
||||
+ requirements.txt 记录依赖
|
||||
```
|
||||
|
||||
## 四、`virtualenv`:功能更丰富的环境创建工具
|
||||
|
||||
`virtualenv` 是需要额外安装的第三方工具。Python 官方打包指南说明,`venv` 是 Python 自带方案,而 `virtualenv` 提供更广的兼容性和额外能力。
|
||||
|
||||
基本命令:
|
||||
|
||||
```powershell
|
||||
virtualenv .venv
|
||||
```
|
||||
|
||||
特点:
|
||||
|
||||
- 主要职责与 `venv` 相同,都是创建隔离环境;
|
||||
- 需要先安装;
|
||||
- 提供更丰富的解释器选择、配置和兼容能力;
|
||||
- 在只需要基础环境隔离的新项目中,通常先用 `venv` 就够了。
|
||||
|
||||
对当前零基础课程,不必同时学习 `venv` 和 `virtualenv`。先理解 `venv`,以后遇到明确需求再使用 `virtualenv`。
|
||||
|
||||
## 五、`pip`:软件包安装器,不是虚拟环境
|
||||
|
||||
`pip` 的职责是把 Python 软件包安装到某个环境。
|
||||
|
||||
推荐命令:
|
||||
|
||||
```powershell
|
||||
python -m pip install 软件包名称
|
||||
```
|
||||
|
||||
这里的关键是“当前这个 Python”:
|
||||
|
||||
- 如果当前 Python 来自 `.venv`,依赖会装入 `.venv`;
|
||||
- 如果当前 Python 来自 Conda 环境,依赖会装入该 Conda 环境;
|
||||
- 如果当前 Python 是全局环境,依赖可能被装入全局环境。
|
||||
|
||||
所以 `pip` 自己不提供隔离,隔离由 `venv`、`virtualenv` 或 Conda 环境等机制提供。
|
||||
|
||||
`pip` 常见能力:
|
||||
|
||||
```powershell
|
||||
python -m pip install 软件包名称
|
||||
python -m pip uninstall 软件包名称
|
||||
python -m pip list
|
||||
python -m pip show 软件包名称
|
||||
python -m pip check
|
||||
python -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
优点:
|
||||
|
||||
- Python 生态中最通用;
|
||||
- PyPI 上的软件包覆盖广;
|
||||
- 与 `venv` 配合简单;
|
||||
- 教程、部署平台和持续集成环境普遍支持。
|
||||
|
||||
需要注意:
|
||||
|
||||
- 安装前必须确认当前解释器;
|
||||
- `requirements.txt` 与环境本身是两回事;
|
||||
- `pip freeze` 会导出当前环境全部软件包,环境不干净时可能带入无关依赖。
|
||||
|
||||
## 六、Conda:环境管理器加跨语言包管理器
|
||||
|
||||
Conda 同时负责环境和包管理。它可以在创建环境时指定 Python 版本:
|
||||
|
||||
```powershell
|
||||
conda create -n python-course python=3.13
|
||||
conda activate python-course
|
||||
```
|
||||
|
||||
安装 Conda 软件包:
|
||||
|
||||
```powershell
|
||||
conda install 软件包名称
|
||||
```
|
||||
|
||||
查看环境:
|
||||
|
||||
```powershell
|
||||
conda env list
|
||||
```
|
||||
|
||||
Conda 环境与普通 `venv` 的重要区别:
|
||||
|
||||
- Conda 可以直接管理环境中的 Python 版本;
|
||||
- Conda 包不局限于纯 Python 包,也能包含本地库、命令行程序等内容;
|
||||
- 软件包来自 Conda channel,例如 `defaults` 或 `conda-forge`;
|
||||
- 环境通常集中保存在 Conda 安装目录的 `envs` 下,也可以使用指定路径;
|
||||
- 环境描述常使用 `environment.yml`。
|
||||
|
||||
Conda 更适合:
|
||||
|
||||
- 数据科学、机器学习和科学计算;
|
||||
- 依赖 NumPy、PyTorch、CUDA 或本地二进制库的项目;
|
||||
- 需要同时管理 Python 与非 Python 软件的环境;
|
||||
- 已经以 Anaconda、Miniconda 或 Miniforge 作为主要 Python 发行方式的团队。
|
||||
|
||||
代价和注意事项:
|
||||
|
||||
- 工具体系比 `venv + pip` 更大;
|
||||
- channel 和包来源会影响解析结果;
|
||||
- Conda 包版本可能与 PyPI 发布节奏不同;
|
||||
- 同一环境混用 Conda 与 pip 时需要保持清晰边界。
|
||||
|
||||
## 七、Conda 环境中能不能使用 pip
|
||||
|
||||
可以,但建议遵守以下顺序:
|
||||
|
||||
1. 创建并激活独立 Conda 环境;
|
||||
2. 优先一次性安装需要的 Conda 包;
|
||||
3. 确认使用的是当前环境中的 pip;
|
||||
4. 只有 Conda channel 没有需要的软件包时,再使用 pip;
|
||||
5. pip 安装后如果还要大规模调整 Conda 依赖,优先考虑重建环境,而不是反复混装。
|
||||
|
||||
示例:
|
||||
|
||||
```powershell
|
||||
conda create -n python-course python=3.13 pip
|
||||
conda activate python-course
|
||||
python -c "import sys; print(sys.executable)"
|
||||
python -m pip --version
|
||||
```
|
||||
|
||||
然后才能确认 pip 指向当前 Conda 环境。
|
||||
|
||||
不建议在一个环境中无计划地交替执行大量 `conda install` 和 `pip install`。两套工具使用不同的软件包格式与依赖信息,复杂项目可能出现一方不知道另一方具体修改了什么的问题。
|
||||
|
||||
## 八、`uv`:速度较快的一体化 Python 工具
|
||||
|
||||
`uv` 是独立工具,不依赖当前 Python 才能启动。它覆盖多项工作:
|
||||
|
||||
- 安装和选择 Python;
|
||||
- 创建虚拟环境;
|
||||
- 安装与卸载 Python 软件包;
|
||||
- 管理 `pyproject.toml` 项目;
|
||||
- 生成并使用 `uv.lock`;
|
||||
- 同步项目环境;
|
||||
- 在项目环境中运行命令。
|
||||
|
||||
仅创建虚拟环境:
|
||||
|
||||
```powershell
|
||||
uv venv
|
||||
```
|
||||
|
||||
使用类似 pip 的接口:
|
||||
|
||||
```powershell
|
||||
uv pip install 软件包名称
|
||||
uv pip list
|
||||
uv pip check
|
||||
```
|
||||
|
||||
完整项目工作流:
|
||||
|
||||
```powershell
|
||||
uv init
|
||||
uv add 软件包名称
|
||||
uv sync
|
||||
uv run python main.py
|
||||
```
|
||||
|
||||
在项目工作流中:
|
||||
|
||||
- `pyproject.toml` 声明项目及直接依赖;
|
||||
- `uv.lock` 记录解析后的精确依赖;
|
||||
- 默认项目环境通常是 `.venv`;
|
||||
- `uv run` 会在运行前确认锁文件和项目环境保持同步。
|
||||
|
||||
官方文档建议:使用 uv 项目工作流时,通过 `uv add` 管理项目依赖,不要把 `uv pip install` 当作项目依赖声明方式。`uv pip` 更适合兼容传统 pip 工作流或手动管理环境。
|
||||
|
||||
## 九、`uv` 与 pip 的关系
|
||||
|
||||
`uv pip` 提供与 pip 类似的命令体验,但 `uv` 并不是 pip 的插件,也不是简单调用 pip。
|
||||
|
||||
可以这样理解:
|
||||
|
||||
```text
|
||||
传统方式:venv + pip + requirements.txt
|
||||
uv 兼容方式:uv venv + uv pip + requirements.txt
|
||||
uv 项目方式:uv + pyproject.toml + uv.lock + .venv
|
||||
```
|
||||
|
||||
如果使用完整 uv 项目工作流,常用命令通常是:
|
||||
|
||||
```powershell
|
||||
uv add
|
||||
uv remove
|
||||
uv sync
|
||||
uv run
|
||||
```
|
||||
|
||||
而不是手动激活环境后不断执行 `uv pip install`。
|
||||
|
||||
## 十、`uv` 与 Conda 的区别
|
||||
|
||||
两者都能管理 Python 和环境,但侧重点不同。
|
||||
|
||||
Conda:
|
||||
|
||||
- 以 Conda 包、channel 和 Conda 环境为核心;
|
||||
- 能管理更广泛的非 Python 依赖;
|
||||
- 在科学计算、数据分析和机器学习生态中常见;
|
||||
- 可以管理 Python、R、系统库和二进制程序等内容。
|
||||
|
||||
uv:
|
||||
|
||||
- 以现代 Python 项目、PyPI、`pyproject.toml` 和锁文件为核心;
|
||||
- 默认使用项目内 `.venv`;
|
||||
- 适合普通 Python 应用、库、工具和 Web 后端;
|
||||
- 依赖操作和环境同步速度通常是其主要优势之一。
|
||||
|
||||
如果项目强依赖 CUDA、本地科学计算库或 Conda channel,Conda 通常更自然。如果项目主要是 PyPI 中的 Python 依赖,uv 项目工作流通常更轻量。
|
||||
|
||||
## 十一、核心对比表
|
||||
|
||||
| 工具 | 创建隔离环境 | 安装 Python 包 | 管理 Python 版本 | 管理非 Python 软件 | 典型依赖文件 | 适合场景 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `venv` | 是 | 否,通常配合 pip | 否,使用已有 Python | 否 | 无,常配合 `requirements.txt` | 入门、普通脚本、Web 项目 |
|
||||
| `virtualenv` | 是 | 否,通常配合 pip | 选择已有解释器 | 否 | 无,常配合 `requirements.txt` | 需要更强环境创建能力 |
|
||||
| `pip` | 否 | 是 | 否 | 通常不负责 | `requirements.txt` | 向现有 Python 环境安装包 |
|
||||
| Conda | 是 | 是 | 是 | 是 | `environment.yml` 等 | 数据科学、机器学习、二进制依赖 |
|
||||
| `uv` | 是 | 是 | 是 | 主要面向 Python 生态 | `pyproject.toml`、`uv.lock` | 现代 Python 项目和 Web 后端 |
|
||||
|
||||
## 十二、应该如何选择
|
||||
|
||||
### 12.1 零基础学习和理解原理
|
||||
|
||||
优先学习:
|
||||
|
||||
```text
|
||||
venv + pip
|
||||
```
|
||||
|
||||
原因是它们能清楚展示“环境隔离”和“包安装”是两个不同职责,也是 Python 官方文档中的基础工作流。
|
||||
|
||||
### 12.2 普通 Python、FastAPI 或 Django 项目
|
||||
|
||||
可以选择:
|
||||
|
||||
```text
|
||||
venv + pip
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```text
|
||||
uv 项目工作流
|
||||
```
|
||||
|
||||
前者通用、容易理解;后者在依赖解析、锁定和同步方面更加一体化。
|
||||
|
||||
### 12.3 数据科学和机器学习
|
||||
|
||||
如果涉及复杂科学计算、CUDA 或系统二进制依赖,可以优先考虑:
|
||||
|
||||
```text
|
||||
Conda
|
||||
```
|
||||
|
||||
必要时在独立 Conda 环境中谨慎补充 pip 包。
|
||||
|
||||
### 12.4 当前教学项目
|
||||
|
||||
当前机器的 `python` 来自 Miniconda,但这不等于每个项目都必须使用 Conda 环境。
|
||||
|
||||
为了理解基础概念,本课程讲义使用 `venv + pip`。以后进入 FastAPI 和 Django 阶段,可以根据学习目标二选一:
|
||||
|
||||
- 继续使用 `venv + pip`,保持通用和透明;
|
||||
- 切换到 uv 项目工作流,学习现代依赖锁定与同步。
|
||||
|
||||
不建议在同一个项目中同时维护 `requirements.txt`、`environment.yml` 和 `uv.lock` 三套互不一致的依赖事实来源。应该选定一种主要工作流。
|
||||
|
||||
## 十三、常见误区
|
||||
|
||||
### 13.1 “pip 创建了虚拟环境”
|
||||
|
||||
不正确。通常是 `venv` 创建环境,pip 向环境安装软件包。
|
||||
|
||||
### 13.2 “激活环境后就安装了依赖”
|
||||
|
||||
不正确。激活只切换当前终端优先使用的解释器和工具,依赖仍需单独安装或同步。
|
||||
|
||||
### 13.3 “Conda 环境就是 Python venv”
|
||||
|
||||
两者都能实现隔离,但内部结构、包格式、依赖来源和管理范围不同,不能简单视为同一个实现。
|
||||
|
||||
### 13.4 “uv pip 就是速度更快的 pip 命令别名”
|
||||
|
||||
不准确。它提供兼容 pip 的操作方式,但 uv 是独立实现,并且还有完整的项目、Python、环境和锁文件管理能力。
|
||||
|
||||
### 13.5 “有锁文件就不需要虚拟环境”
|
||||
|
||||
不正确。锁文件描述应该安装什么,虚拟环境保存实际安装结果,两者职责不同。
|
||||
|
||||
### 13.6 “把 `.venv` 复制到另一台机器就能复用”
|
||||
|
||||
不推荐。虚拟环境可能包含绝对路径和平台相关文件。应在新机器重新创建环境,并根据依赖文件安装或同步。
|
||||
|
||||
## 十四、推荐记忆方式
|
||||
|
||||
```text
|
||||
venv / virtualenv:创建隔离房间
|
||||
pip:向房间里安装 Python 包
|
||||
Conda:创建房间,并管理 Python 与更广的软件
|
||||
uv:创建房间,并管理现代 Python 项目、依赖和锁文件
|
||||
```
|
||||
|
||||
## 十五、官方资料
|
||||
|
||||
- [Python 打包指南:使用 pip 和 venv](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/)
|
||||
- [Python 打包指南:安装软件包](https://packaging.python.org/en/latest/tutorials/installing-packages/)
|
||||
- [virtualenv 官方文档](https://virtualenv.pypa.io/en/stable/)
|
||||
- [Conda:管理环境](https://docs.conda.io/projects/conda/en/stable/user-guide/tasks/manage-environments.html)
|
||||
- [Conda:管理软件包](https://docs.conda.io/projects/conda/en/stable/user-guide/tasks/manage-pkgs.html)
|
||||
- [uv:Python 环境](https://docs.astral.sh/uv/pip/environments/)
|
||||
- [uv:项目结构、环境与锁文件](https://docs.astral.sh/uv/concepts/projects/layout/)
|
||||
- [uv:从 pip 工作流迁移到 uv 项目](https://docs.astral.sh/uv/guides/migration/pip-to-project/)
|
||||
Reference in New Issue
Block a user