Poetry--轻量级的python包管理器
摘要
- Poetry是一个轻量级的python包管理器,其目标是帮助开发者快速、轻松地构建、发布和分享python包。说它轻量,是与 conda 相比 poetry 更轻量,同时与
venv + pip
Python--virtualenv 的方式相比具有如下优点:- 使用缓存机制,避免重复下载依赖包
- 包管理上更加精确,删除不需要的包时会同时删除与其关联的且没有被使用的那些依赖包,避免无用的依赖包造成打包体积过大
- 打包和发布更加简单,只需要一个命令就可以打包和发布
安装
-
参考官方文档Installation
1 | # 官方推荐使用pipx安装,当然也可以使用 pip |
pipx简介
-
pipx 是一个 Python 包管理工具,使用pipx安装工具包时,每个工具都会被安装在一个独立的虚拟环境中,避免不同工具之间的依赖冲突。
-
场景:两个工具依赖不同版本的同一个库
假设我们有两个命令行工具:工具A 依赖于 requests 库的版本 2.27.1。
工具B 依赖于 requests 库的版本 2.31.0。如果使用 pip 安装
工具会被安装到全局环境,共享相同的依赖版本:1
2pip install toolA # 安装时会安装 requests 2.27.1
pip install toolB # 安装时会将 requests 升级到 2.31.0结果:
当你运行工具A时,它可能会报错,因为它依赖的 requests 2.27.1 已被 requests 2.31.0 替换。
全局环境中的所有工具都共享一个 requests,版本冲突不可避免。如果使用 pipx 安装
每个工具会被安装到独立的虚拟环境中,各自的依赖互不影响:1
2pipx install toolA # 在虚拟环境A中安装 toolA 和 requests 2.27.1
pipx install toolB # 在虚拟环境B中安装 toolB 和 requests 2.31.0结果:
虚拟环境A 只包含 toolA 和它的依赖 requests 2.27.1。
虚拟环境B 只包含 toolB 和它的依赖 requests 2.31.0。
工具之间完全隔离,不会因为依赖版本冲突而导致问题。 -
所以,当需要安装全局命令行工具时,使用pipx是个很好的选择
-
pipx 的安装
1 | # 安装pipx |
查看所有命令
我已经将其翻译为中文
1 | $ poetry list |
常用命令
-
这里只对日常开发中比较常用的命令进行简要说明,详细介绍可以参考官方文档
new : 创建项目
1 | # 按照默认规则创建一个基于 poetry 的项目 |
init : 初始化一个已有的项目目录
1 | # 假设我们已经有个项目目录,目录名称为 poetryDemo |
-
上面的方式在初始化时会询问你相关的信息,如果你希望都用默认值的话,可以使用如下命令
1 | poetry init -n |
config : poetry的全局配置
-
查看全局配置
1 | $ poetry config --list |
-
修改全局配置
1 | # 修改全局配置,此后会在项目目录下创建 .venv 目录存放虚拟环境 |
env : 虚拟环境管理
-
Poetry 会在你第一次运行某些命令(如
poetry shell
或者poetry add somepackage
)时自动创建虚拟环境。 -
不过这种时候都是使用系统默认的python来创建虚拟环境,如果系统中安装了多个python,则可以通过如下方式设置虚拟环境要使用哪个python版本
-
创建/切换虚拟环境
1 | # 指定python的版本,这会从python的默认安装路径下查找对应的版本 |
-
查看当前项目的虚拟环境信息
1 | # 创建一个基于 python3.13 的虚拟环境 |
-
注意,当
virtualenvs.in-project
被设置为true
时,即只在项目目录下创建虚拟环境时,只会保留一个环境,即.venv
-
切换到新的虚拟环境时会全新创建一个新的环境,原先的环境会被删除,所以要使用
poetry install
命令重新安装依赖
1 |
|
依赖包管理
-
add : 安装依赖包
这个命令会修改 pyproject.toml 文件,在 [tool.poetry.dependencies] 部分添加新的依赖项。还会自动更新 poetry.lock 文件,锁定依赖的确切版本。
1 | # 安装依赖,安装后会将依赖信息写入 pyproject.toml 中 |
-
show : 查看依赖包
1 | # 查看当前项目都需要哪些依赖,这些依赖不一定都安装了,它只是解析 pyproject.toml 中的声明来解析依赖树 |
-
remove : 删除依赖包
1 | # 删除依赖,此时会将当前包及其所有依赖一块删除 |
-
search : 搜索远程仓库
1 | # 搜索远程仓库 |
-
install 和 update : 安装和更新依赖包
在 Poetry 中,install 和 update 是两个常用的命令,但它们的作用和使用场景不同-
poetry install
的作用是根据现有的 poetry.lock 文件来安装依赖,确保安装的依赖版本与锁文件中记录的版本完全一致。
核心特点:- 安装锁定的版本:它只会安装 poetry.lock 文件中指定的版本,即使 pyproject.toml 文件中定义的版本范围已经有更新版本。
- 重现依赖环境:适用于团队协作或部署环境,确保所有人或机器安装的依赖版本完全相同。
- 锁文件存在时更高效:如果 poetry.lock 文件存在,poetry install 不会重新解析依赖树。
- 首次运行时生成锁文件:如果没有 poetry.lock 文件,poetry install 会解析依赖并生成锁文件。
使用场景: - 新克隆的项目,需要安装依赖环境。
- 部署生产环境,确保依赖版本的稳定性。
- 重新安装之前已定义的依赖(例如清空了虚拟环境)。
-
poetry update
的作用是根据 pyproject.toml 文件中定义的依赖范围重新解析依赖树,并更新 poetry.lock 文件为最新的版本。
核心特点:- 更新到最新版本:它会尝试安装依赖范围内的最新版本,并更新 poetry.lock 文件。
- 解析新的依赖树:即使 poetry.lock 文件存在,poetry update 也会忽略它并重新解析依赖。
- 更改锁文件:它会覆盖现有的 poetry.lock 文件,因此团队其他成员需要重新运行 poetry install 以同步。
使用场景: - 更新依赖到最新版本(在依赖范围内)。
- 当添加新依赖后,想要安装并更新锁文件。
- 修复可能的版本冲突或不兼容问题。
-
lock : 锁定依赖包
-
poetry lock
是 Poetry(一个 Python 包管理工具)中的一个命令,用于锁定项目的依赖关系。使用这个命令可以创建或更新poetry.lock
文件,确保你的项目中所使用的每个包的版本都被明确记录下来。这样做对于项目的可复现性和稳定性至关重要。 -
实际上,当运行
poetry install
、poetry update
或者poetry add
等命令时, poetry 都会根据
pyproject.toml
文件中的依赖范围,解析依赖树,并在项目目录下创建或更新poetry.lock
文件。 -
当我们手工修改了
pyproject.toml
文件中的依赖范围,此时又不想立刻更新依赖,而是希望在某个时机再更新,此时就可以使用poetry lock
命令,先锁定这些依赖,之后再通过poetry install
命令安装。 -
可以使用
poetry check
命令检查pyproject.toml
文件 与poetry.lock
文件的一致性。
1 | # 比如我手工删除了 `pyproject.toml` 文件中的某个依赖 |
小贴士
- 注意,此时通过
poetry show
查看不到那个手工删除的依赖包,但实际上依赖依旧在于虚拟环境中 - 所以尽量避免手工删除依赖,而是通过
poetry remove
命令来删除依赖
source : 镜像源管理
-
默认情况下都是从Pypi的官方仓库下载,国内一般需要指定镜像源来加速下载
1 | # 添加镜像源,默认就是主要源,注意该方式只对当前项目有效 |
运行
这里以一个小示例来说明这个功能
-
创建一个新的项目
1 | $ poetry new poetryDemo |
-
在包目录下创建 array_util.py,内容如下
1 | import numpy as np |
-
安装依赖
1 | $ poetry add numpy |
-
运行,两种方法
poetry run
1
2
3
4
5
6
7
8
9
10
11
12
13$ poetry run python array_util.py
均匀分布随机数组:
[[7.44623063 1.89415788 4.81008329 4.25556572]
[3.31925154 6.44037063 5.3216543 7.54950573]
[3.97160747 5.04800698 3.28299934 3.42841887]]
正态分布随机数组:
[[ 0.49671415 -0.1382643 0.64768854]
[ 1.52302986 -0.23415337 -0.23413696]]
随机整数数组:
[[10 10 3 7 2]
[ 1 11 5 1 0]
[11 11 16 9 15]
[14 14 18 11 19]]poetry shell
: 此时会开启一个新的shell,并开启虚拟环境
1
2
3
4
5
6
7# 开启虚拟环境
$ poetry shell
Spawning shell within /Users/hanqf/Library/Caches/pypoetry/virtualenvs/poetrydemo-fyqYbfje-py3.11
Restored session: 2024年11月21日 星期四 15时31分52秒 CST
➜ poetrydemo emulate bash -c '. /Users/hanqf/Library/Caches/pypoetry/virtualenvs/poetrydemo-fyqYbfje-py3.11/bin/activate'
# 在虚拟环境下运行
$ python array_util.py
打包和发布
-
接着上面的项目
-
打包
1 | # 会在项目目录下创建 dist 目录,并将打好的包存放于此 |
-
发布
-
首先要先在PyPI上注册个帐号,需要开启“双要素身份验证 (2FA)”,否则不能获取发布时的API令牌。
-
获取API令牌
-
发布,不过这次发布提示包名已经存在了
1 | # 发布时提示包名已经存在了 |
-
先修改包名,直接编辑 pyproject.toml 即可,将name属性修改为“hqf_poetrydemo”,然后将包目录的名称也修改为这个
mv poetrydemo hqf_poetrydemo
,并删除dist目录,之后重新打包poetry build
,再次发布
1 | $ vim pyproject.toml # 将name属性修改为“hqf_poetrydemo” |
-
之后就可以在其它项目中安装这个包了
1 | # pip install |
self update
: 升级 poetry 版本
-
self 相关命令主要用于 poetry 自身安装插件使用
-
估计插件功能目前还不成熟,官网也没有进行详细的说明,并且 windows 下无法使用,所以这里不讨论。
-
self
命令下目前只需要记住一个命令:self update
: 升级 poetry 版本
1 | $ poetry self update |
debug resolve
: 查看包的依赖关系
1 | # 只查看,不安装 |
cache : 缓存管理
-
poetry一个很重要的功能就是缓存安装包,可以
减少
相同的安装包被重复下载。为什么是减少而不是避免呢?因为不同的镜像源的包是分别缓存的。 -
通过
poetry config --list
可以看到cache-dir
的地址,这里就是缓存下载包的目录。 -
以下是一些常见的使用场景
- 解决依赖安装问题:
如果你在安装或更新依赖时遇到问题(例如,某个包无法正确安装或版本不对),清空缓存可以帮助你确保 Poetry 重新下载所有必要的文件,从而解决问题。 - 清理磁盘空间:
如果你的项目很多或者经常修改依赖项,缓存可能会变得非常大。使用 poetry cache clear 可以帮助释放磁盘空间,特别是当你不经常使用某些包时。 - 测试最新版本的依赖:
如果你想测试某个包的新版本是否解决了某个问题,或者想确保你使用的确实是最新的版本,清除缓存可以强制 Poetry 从远程仓库重新下载最新的包。 - 环境变化:
如果你的开发或生产环境发生了变化(例如,切换了操作系统、更新了 Python 版本等),清除缓存可以帮助你确保依赖项在新环境中正确安装。 - 调试依赖问题:
在调试依赖项问题时,有时候清除缓存可以帮助你确定问题是否与缓存中的旧版本有关。 - CI/CD 环境的一致性:
在持续集成或持续部署 (CI/CD) 环境中,为了确保每次构建都基于最新的依赖,有时会在构建脚本中包含清除缓存的步骤。
- 解决依赖安装问题:
1 | # 查看缓存列表,这里会按镜像源进行分组 |