
我本科是生物信息背景,本科的时候主要用 Python 和 R 做分析、画图,对于生信人来说,一般使用 conda 来管理环境,conda 既能安装 python 还能安装 R
之前分享过的 python 配置笔记:安装Python,我选择miniforge而不是Anaconda
2022 年到 2025 之间,由于研究生科研项目的需求,主要用 Matlab 来处理图像数据、写 GUI 程序、与硬件进行通信,此外论文画图我也改用 Matlab
过去分享的 Matlab 使用文章
✦ Matlab 2025a 尝鲜:越来越像VSCode,体验不错值得升级,但注意兼容问题
✦ VSCode 配置 Matlab 运行环境:写代码效率up up!
✦ Matlab 和 Python选哪个?对不起,小孩子才做选择!我都要!
✦ Matlab 统一Figure大小的正确姿势:统一有legend和无legend的图大小
而从今年开始,由于新项目的需求,我又重新把 Python 捡了起来。结果发现,现在越来越多的 Python 项目,其依赖管理文件已经不再是传统的 requirements.txt,而是改成了 pyproject.toml
比如:https://github.com/napari/napari

https://github.com/DeepLabCut/DeepLabCut

了解了下,在以前,Python 项目通常会有很多个配置文件(例如 setup.py、setup.cfg、requirements.txt、.flake8、pytest.ini 等)。而现在,官方推荐将这些内容全部整合到 pyproject.toml 这一个文件中。
同时也发现很多项目开始用 uv 来开发 Python 项目,比如前面的 DeepLabCut、napari 都是用 uv 来管理项目依赖的。
于是,最近我尝试体验了一下 uv 这个工具,用它来开发 Python 项目,开发体验确实可以用一个字来形容——爽!
✦ 一个工具取代其他工具: pip、pip-tools、pipx、poetry、pyenv、virtualenv。
✦ 安装包速度快:使用 rust 编写,相比 pip,安装速度快到 10–100 倍!

✦ 自动更新和维护项目依赖:这是我最喜欢的一点了,再也不用手动维护 requirements.txt 了,uv add 就会自动生成和更新 pyproject.toml,pyproject.toml 会记录 python 版本和用的包的版本要求,这点和前端的 npm 很像,很舒服。
✦ 可以快捷打包和发布包到 PyPI:uv build 和 uv publish 即可快捷打包发布
我个人认为 conda 和 uv 使用并不冲突,可以理解为 uv 是 Python 项目开发工具,可以让开发者快速安装项目依赖以及管理项目依赖。而 conda 是环境管理工具,更侧重用户日常使用不同环境来安装并运行各种不同程序,很方便数据分析等场景。
比如前面的 [DeepLabCut](https://github.com/DeepLabCut/DeepLabCut),虽然用 uv 进行开发,但是安装教程可还是推荐用 conda 来安装的。

另外,conda 的一个重要优势是:它不仅能管理 Python 包,还可以安装非 Python 的二进制库和工具。
所以根据自己的需求来选用就可,不需要因为有了 uv 就放弃 conda。
✦ GitHub:https://github.com/astral-sh/uv
✦ 英文文档:https://docs.astral.sh/uv/
✦ 中文文档;https://uv.oaix.tech
Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
macOS 和 Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
运行 uv init 即可快速初始化项目,初始化项目的同时会自动创建 main.py、README.md、.gitignore、pyproject.toml、.python-version,这五个文件
uv init
如果想新建一个文件夹作为项目,而不是以当前文件为项目,使用
uv init 项目名
如果初始化项目要指定 python 版本,使用下面命令
uv init --python 3.14
可以使用 uv python list 查看 uv 可安装的 python 版本,目前最低只能是 python 3.7

如果后续要修改 python 版本,使用下面命令
# uv python install 3.14 # 如果没有安装过python版本,需要先安装
uv sync --python 3.14
以后也可以使用 uv sync 命令更新项目依赖信息
如果你这个项目一开始就打算未来要发布到 PyPI 上给人使用,需要添加 --package 后缀,这样项目初始化的时候,项目结构和 pyproject.toml 都适配了 python 的包格式
uv init --package

# 添加项目依赖
uv add pyside6
# 一次添加多个依赖项
uv add pyside6 numpy
# 移除项目依赖
uv remove numpy
# 查看依赖树
uv tree
uv 也支持脚本级临时安装包进行测试,这样不污染项目环境
# 向脚本添加隔离依赖项
uv add --script example.py requests
# 向脚本移除隔离依赖项
uv remove --script example.py requests
如果手动修改了 pyproject.toml,需要同步环境中的依赖,安装缺失的包,移除多余的包,可用 uv sync 进行同步依赖
uv sync
如果过去用的是 pip,有 requirements.txt,可以用 uv add -r requirements.txt 来进行一键迁移
使用 uv run 文件.py 的方式运行脚本,会自动启动环境并运行代码
uv run main.py
还可以运行脚本时指定特定 python 版本
uv run main.py --python 3.13
uv 虽然默认会使用硬链接来复用缓存中的包文件,以降低重复下载保存带来的空间和时间开销,但要求 cache 目录必须和 venv(也就是项目文件夹)在同一个文件系统上。否则, 将会触发 copy 复制文件,并会出现警告 Failed to hardlink files; falling back to full copy,不仅速度慢,还占用空间。
对于 Windows 用户而言,默认的 uv 缓存文件夹在 C 盘,可使用 uv cache dir 查看缓存文件夹,但很多人并不会在 C 盘写代码。
如果要改动缓存文件夹到日常 Coding 所在的盘,可打开 PowerShell 进行永久修改
setx UV_CACHE_DIR E:\.uv-cache
修改完之后可以运行 uv sync 更新项目环境
除了修改缓存文件夹路径,还有一个方法是修改 link mode 为 symlink 符号链接,打开 PowerShell 运行
setx UV_LINK_MODE symlink
但是 uv 官方并不推荐这种做法,因为符号链接就是快捷方式,一旦缓存文件被删除,之前的包就都无法使用了,而硬链接则没有这个问题
参考资料
✦ [在 Windows 上使用 uv 时的 hardlink 警告:Failed to hardlink files; falling back to full copy 完美解决方案 - LexLuc - 博客园](https://www.cnblogs.com/LexLuc/p/19429840)
✦ [Failed to hardlink files: Issue with ruff cache · Issue #7285 · astral-sh/uv](https://github.com/astral-sh/uv/issues/7285)
uv cache clean
uv 上传包到 PyPI 非常快捷,核心就两步:build + publish。
✏️ Note
注意:如果项目想要上传到 PyPI,最好一开始就用 uv init --package 命令进行初始化,这样项目文件结构和 pyproject.toml 都会自动搞好

1、设置 PyPI Token
获取 PyPI Token:前往 https://pypi.org/manage/account/,点击 Add API token,获取 Token

设置 Token
✦ Windows:打开 Powershell,设置永久环境变量
setx UV_PUBLISH_TOKEN "pypi-你的pypi-token"
✦ Linux/MacOS
export UV_PUBLISH_TOKEN="pypi-你的pypi-token"
2、打包
uv build

3、发布到 PyPI
uv publish
在 pyproject.toml 里通常写的是范围,比如:
dependencies = [
"fastapi>=0.110,<1.0",
]
但实际安装时,到底是 0.110.0、0.111.1 还是别的版本,需要解析后才能确定。
uv.lock 会记录:
✦ 具体安装了哪些包
✦ 每个包的精确版本
✦ 它们的传递依赖(子依赖)
✦ 还包括来源、哈希、平台相关信息
这样别人或 CI 再安装时,就能得到一致的依赖结果