谈 Python 环境配置
浅风

写在前面

时隔三年重拾博客,这三年经历了太多太多(读研、出国、考博)。每次想继续写一写那些没有写完的内容,都是被脑海中各种抗拒的声音说服,索性把之前的文章删掉,从头开始,也落得一番清净。这一次是为了给师哥师姐师弟师妹写一篇 Python 环境配置的教程,顺便聊聊一些常规的机器学习框架如何正确配置。也希望在读的各位可以顺利跟着我的步骤,不要让配环境成了阻碍各位科研的绊脚石。

0 - Pip 是什么,Uv 又是什么?

众所周知,Python 自带很多标准库,用来负责最基础的功能,比如 io、sys 和 json 等等。高级功能通常需要用到第三方库,Pip 作为 Python 自带的包管理器,可以使用户简单方便地通过一行指令 pip install 从 Pypi 下载用于各类研究的各类第三方库。

听起来很方便对吧?但是(补豪是但是!),一方面,如果你不在虚拟环境中执行 pip install,你将会在你的全局 Python 环境安装各种项目需要的各种包。如果不同项目指定的包依赖不同,你可能还需要重复执行 pip installpip uninstall,这不仅浪费你的时间和耐心,也是对咱们严谨的学术态度的不尊重!另一方面,Pip 很慢,超级慢,巨慢!有人看完上面的内容可能会问,我每个项目直接初始化独立的虚拟环境不就好了吗,为什么不用 Pip,为什么不用官方的工具?你看你__,你绝对没有体会过每个项目都下载一个近 1G 的 pytorch 时的煎熬。读到这里你可能会想到,我为什么要在多个项目都重复下载同一个包?我直接找一个目录缓存起来等需要时复制过去不就好啦?恭喜你成功解锁了 Uv —— An extremely fast Python package and project manager, written in Rust(一个用 Rust 编写的极快的 Python 包和项目管理工具),有多快?附上官方测试图👇

一个工具,不仅可以代替传统的 Pip、Pipx 和 Poetry 等包管理工具,也能代替 Conda、virtualenv 和 pyenv 等虚拟环境管理工具,并且它还比其他所有工具快上 10 - 100 倍!有此工具,何愁配环境?!

1 - 安装 Uv

Uv 可以通过 Pip 安装,也可以不依赖 Python 直接安装。这里推荐大家直接安装,因为如果通过 Pip 安装的 Uv 所依赖的 Python 环境一旦出现问题,Uv 就成了无能的丈夫,没招了。

官方安装脚本的食用方式为以管理员身份运行 Powershell,运行以下命令:

1
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

如果安装过程中出现任何报错,大概率是你的网络环境出了问题,换用手机热点或者使用科学上网一般都可以解决。

这里插个话,我更推荐使用 Scoop 安装,对网络要求不高并且方便更新和管理,安装方式为以管理员身份运行 Powershell,依次运行以下命令:

1
2
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
1
scoop install main/uv

安装成功后,新开一个 Cmd,运行以下命令确认 Uv 已成功安装:

1
uv self version

前面讲到 Uv 有缓存特性,我们需要稍微配置一下使其生效。由于跨盘转移数据会导致性能损耗,所以我们需要在最常运行代码的盘中创建一个全局缓存文件夹来存放 Uv 缓存的包,比如我们常在 D 盘跑代码,那就在 D 盘新建一个文件夹名为 UvCache(名字可以随便取),然后运行以下命令使 Uv 更改全局缓存目录至 D:/UvCache

1
uv cache dir --cache-dir D:/UvCache

运行以下命令确认修改成功:

1
uv cache dir

2 - 初始化项目

接下来可以使用 Uv 来管理任何的 Python 项目辣!

对于所有项目,先看看根目录下有没有 .venv.env 或者类似名字的文件夹,这是你的 IDE 或者其他环境管理工具曾经创建的虚拟环境,建议删除以防止出现不可预见的问题。

对于现有项目,如果项目根目录下已经有了 pyproject.toml 文件,打开 Cmd 运行:

1
uv sync --all-extras

Uv 会帮你搞定:Python 下载、依赖安装、依赖兼容测试和包预编译等等几乎所有前期工作(当然前提是这个项目的配置写的没问题,有问题如何解决就不是这篇文章的重点了)。

如果项目下不存在 pyproject.toml,只有 requirements.txt,则先运行以下命令创建 pyproject.toml 文件(如果可以确定项目使用的 Python 版本,在下面的命令最后加入 --python <Python版本号>):

1
uv init

再运行以下命令安装依赖即可:

1
uv add -r requirements.txt

至此,常规项目的依赖管理和初始化完成。是不是很简单!

对于既没有 pyproject.toml 又没有 requirements.txt 的仓库,你可以通过查看项目 README.md 和每个 Python 文件最上方的 import 语句来初步判断项目使用的 Python 版本和依赖项,通过以下命令创建特定 Python 版本的虚拟环境:

1
uv init --python <Python版本号>

通过以下命令添加依赖项(可以多个一起添加,并且可以通过 ==>=<= 指定版本范围):

1
uv add <lib1> <lib2> <lib3>

对于这种项目,朋友,祝你好运!

3 - 依赖管理和运行代码

上面说了那么多 pyproject.toml,这是一个什么文件呢?

简单来说,这是现代 Python 项目的通用配置文件,它在 2016 年被引入,目的是取代过去零散的配置文件(setup.pyrequirements.txtsetup.cfg 等),将项目的所有配置集中到一个标准化的文件中。它使 Python 项目变得结构化、标准化的同时也能配合 Uv 进行极速的依赖安装和可靠的项目环境管理。

典型的 pyproject.toml 配置如下,包含了环境信息、依赖信息、可用脚本信息和一些配置信息,这些配置都是自解释的,很容易理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[project]
name = "02"
version = "0.1.0"
description = ""
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"imbalanced-learn>=0.14.1",
"lightgbm>=4.6.0",
"ngboost>=0.5.8",
"numpy>=2.4.0",
"openpyxl>=3.1.5",
"pandas>=2.3.3",
"scikit-learn>=1.8.0",
"xgboost>=3.1.2",
]

[project.scripts]
pre_process = "scripts.s0_pre_process.pre_process:main"
feature_select = "scripts.s1_feature_select.feature_select:main"

[project.optional-dependencies]
dev = [
"mypy>=1.18.2",
"ruff>=0.14.6"
]

[tool.setuptools]
packages = ["scripts"]

[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"

[tool.uv]
required-environments = [
"sys_platform == 'win32'"
]

[tool.ruff]
exclude = ["docs"]

[tool.ruff.lint]
select = ["E","F","UP","B","SIM","I"]

[tool.mypy]
disable_error_code = ["import-untyped"]
exclude = ["docs"]

我推荐的 pyproject.toml 配置也为上面的形式,大家可以复制自己更改使用。这份配置还包含了两个开发依赖项(Ruff 和 Mypy)用于代码检查和格式化,并且搭配了一些规则集,方便大家约束自己的代码风格(常用命令为 uv run ruff check <dir/code>uv run ruff format <dir/code>uv run mypy <dir/code>,其他高阶玩法请使用 uv run <ruff/mypy> --help 了解)。这套配置搭配合理的文件结构可以实现非常条理的项目管理,推荐的文件结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
example/
├── datas/ # 数据目录
│ ├── data/ # 处理后的数据
│ ├── output/ # 输出结果
│ └── raw_data/ # 原始数据
├── docs/ # 文档目录
├── scripts/ # 脚本目录
│ ├── __init__.py
│ ├── s0_pre_process/ # 预处理模块
│ │ └── pre_process.py
│ └── s1_feature_select/ # 特征选择模块
│ └── feature_select.py
├── README.md # 项目自述文件
├── .gitignore # Git 配置文件
├── pyproject.toml # 项目配置文件
└── uv.lock # 依赖锁定文件

Uv 的依赖管理很简单,只需三个命令:

  • uv add <package>:添加依赖
  • uv remove <package>:删除依赖
  • uv sync --all-extras:同步依赖

在使用 uv add 时,如果你不指定版本,Uv 会帮你下载和当前环境适配的最新版本依赖,并且在 pyproject.toml 中标注。

使用 Uv 运行代码也十分简单,只需 uv run <code> 即可,如果你在 pyproject.toml 中配置了 [project.scripts],那么你也可以使用 uv run 来运行你配置的代码文件别名。

4 - 与 IDE 集成

接下来该聊聊如何在 IDE 中集成 Uv 了。其实一般常用的 Python IDE(Pycharm、Vscode)在首次打开项目文件夹时都会自动启用项目根目录下的 .venv 虚拟环境,所以其实在上上步初始化虚拟环境后就已经不需要进行额外的操作了,在 IDE 中直接打开你的项目文件夹即可。

如果你之前手动配置过,只需点击 IDE 右下角的解释器管理,选中当前项目根目录的 .venv 虚拟环境即可。

说一些题外话:和 Vscode 相比,Pycharm 还是太重了。咱们组一般的编程任务还用不到如此复杂的 IDE,所以我推荐使用 Vscode 即可,这里推荐一个 Vscode 环境管理插件 -> Python Environments,如果你电脑上不仅有 Uv 还有 Conda / Poetry,这个插件可以帮助你更方便地管理所有的虚拟环境。

5 - Pytorch 安装

现有的机器学习框架最难配置的当属 Pytorch 了,因为其在 Pypi 中发布的包并不支持 GPU 加速,只有在其官网的 Index 中下载的才可以支持 GPU 加速。不过 Uv 显然考虑到了这一点,要安装具备 GPU 加速能力的 Pytorch 时,只需在 pyproject.toml 中添加以下几行(这是适配 CUDA 13.0 的配置,需要适配其他 CUDA 版本时只需调整下方 cu 后面的数字编号即可):

1
2
3
4
5
6
7
8
9
10
11
12
[[tool.uv.index]]
name = "pytorch-cu130"
url = "https://download.pytorch.org/whl/cu130"
explicit = true

[tool.uv.sources]
torch = [
{ index = "pytorch-cu130", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
torchvision = [
{ index = "pytorch-cu130", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]

然后执行:

1
uv add torch torchvision

6 - 结语

配环境这件事,说难也难,说简单也简单。难的是传统方式下各种依赖冲突、版本不兼容的折磨,简单的是只要用对工具,一切都能迎刃而解。希望这篇教程能帮助大家彻底告别配环境的噩梦,把更多时间和精力投入到真正有价值的科研工作中。

Uv 作为新一代的 Python 环境管理工具,不仅速度快,更重要的是它规范了项目管理方式,让代码的复现和分享变得简单可靠。虽然刚开始可能需要一点学习成本,但相信我,用习惯之后你会感谢自己当初的选择。

如果在配置过程中遇到任何问题,欢迎随时交流讨论。科研路上我们互相帮助,共同进步。最后祝大家科研顺利,代码无 Bug,论文高产!🎓