- 约1846字
- 技术
- 2023年12月15日
最近 5 年中,陆陆续续在用 Python 做一些业余开发工作,写过 web 服务端和 cli 程序。做过的项目有涉及数据统计和自动化交易,用得比较多的库是 pandas。用 Python 来处理一些基础的编程需求,特别方便,写完就运行,无需考虑编译问题(相对 Java
和 Nodejs
)。但对 python 的依赖管理工具没有系统的学习,大概知道可以通过 venv
来做不同项目的依赖隔离,可以通过 requirement.txt
来记录项目的依赖。遇到几次本地环境和服务器环境依赖包版本不一致,也没有细究,只做到了能运行就行,不求甚解。
通过询问 ChatGPT 和参考 GitHub 项目介绍,了解到目前比较流行的 python 包管理器 Pipenv
和 Poetry
,在依赖解析和安装方面性能上 Poetry 性能更好。今天花了点时间系统的学习和试用了 Python 的包依赖管理 Poetry。为了更好的理解,先回忆下比较熟悉的 Node.js 依赖包管理方式。
一、Node.js 依赖项管理回顾
近几年工作中用得最多的是 Node.js,流行的依赖管理有 npm
(nodejs 自带)、 yarn
、pnpm
等。它们通过 package.json
, package-lock.json
和 yarn.lock
来记录依赖项。 它们之间关系如下:
1. 依赖项定义package.json
:
package.json
文件定义了项目所需的各种依赖(包括直接和开发依赖)。- 它列出的是高级别的(或者说是直接的)依赖,不包括这些依赖自己的依赖。
- 在这个文件中,依赖的版本可以是范围,而不是固定的版本。例如,使用 ^1.0.0 表示接受该版本以及任何兼容的次要更新。
2. 锁定依赖版本,如package-lock.json
:
不同包管理工具的依赖锁定版本文件不同,npm 对应的是 package-lock.json
,yarn 对应的则是 yarn.lock
,以下为 yarn.lock
为例。
yarn.lock
文件提供了安装的每个依赖包的确切版本信息,且包括所有间接依赖(即依赖的依赖)。- 这个文件确保了所有开发者和部署环境安装相同版本的依赖,从而避免了“在我机器上能运行,在你的机器上却不能”的问题。
- 该文件是自动生成的,记录了整个依赖树及其确切的版本信息,包括包的来源和完整的依赖关系。
二、了解 Python 包管理器 poetry
Poetry
是一个用于 Python 项目的依赖管理和打包工具,旨在简化和改善 Python 包的创建和管理过程。它需要 Python 版本在 3.8 以上,在 Linux,Mac,Windows 都可以很好的工作。
(一)安装 poetry
Warning
Poetry 应该始终安装在专用的虚拟环境中,以将其与系统的其他部分隔离开来。在任何情况下,它都不应该安装在由 Poetry 管理的项目环境中。这可以确保 Poetry 自己的依赖项不会意外升级或被删除。
这里我们通过 pipx
工具来安装 Poetry,pipx 是一个用于在隔离的环境中安装和运行 Python 应用的工具。
1. 先安装 pipx
macOS
# 先安装 pipx brew install pipx pipx ensurepath # 命令行自动完成(通过 tab 键快速完成命名输入) pipx completions
ubuntu 23.04 或以上
sudo apt update sudo apt install pipx pipx ensurepath
ubuntu 22.04 或以下
python3 -m pip install --user pipx python3 -m pipx ensurepath
2. 使用 pipx 安装 poetry
pipx install poetry
(二)使用 poetry
1. 创建新项目
poetry new poetry-demo
此时会创建 poetry-demo 目录,其结构如下:
poetry-demo
├── pyproject.toml
├── README.md
├── poetry_demo
│ └── __init__.py
└── tests
└── __init__.py
其中 pyproject.toml
文件相当于 Node.js 中的 package.json
,它将协调项目及其依赖项。
2. 为一个旧项目增加添加 poetry
cd pre-existing-project
poetry init
3. 通过 poetry 运行 Python 脚本
poetry run python -m xxx.xxx
4. 添加依赖
有两种方式添加依赖:
直接更新
pyproject.toml
文件中的tool.poetry.dependencies
部分,然后运行poetry install
命令安装它。[tool.poetry.dependencies] requests = "^2.31.0"
通过命令行运行
poetry add
命令,它会自动找到一个合适的版本约束,自动更新pyproject.toml
文件,并安装包和子依赖项。poetry add requests
安装依赖后,会生成依赖版本锁定文件 poetry.lock
,相当于 nodejs 中的 yarn.lock
文件。poetry.lock
锁定了项目依赖的具体版本,无论在什么时间、什么环境安装依赖,Poetry 都会根据这个文件中记录的版本来安装,确保在不同环境中依赖的的一致性。
Note
为了保证在不同环境中,依赖包版本的一致性,应该将 poetry.lock
文件放到版本控制系统中。
5. 删除依赖
可以通过 remove
来删除依赖包。
poetry remove package_name
6. 自定义镜像(可选)
poetry 通过 PyPI 软件仓库来下载依赖。如果在国内访问默认的镜像速度很慢,可以通过在 pyproject.toml 末尾添加下面的内容来设置自定义镜像源:
[[tool.poetry.source]]
name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple/"
priority = "primary"
[[tool.poetry.source]]
name = "PyPI"
priority = "primary"
附常用的国内 PyPI 镜像列表:
- 阿里云 https://mirrors.aliyun.com/pypi/simple/
- 豆瓣 https://pypi.doubanio.com/simple/
- 网易 https://mirrors.163.com/pypi/simple/
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
(三)完成
通过以上 pipx 和 poetry 工具的基础使用,就实现了 python 项目的依赖包管理。如需更多信息,可以参考 poetry 官方网站 和 GitHub 项目页面 。
三、poetry 相关问题
1. 安装依赖问题解决
发现有时候使用 poetry add package-name
安装依赖包时,会出现错误,可以尝试:
- 先使用
poetry run pip install package-name
来安装,此时不会将依赖写入pyproject.toml
文件。 - 再运行
poetry add package-name
,这时其实不会再次安装,但是会将依赖到写入pyproject.toml
和poetry.lock
文件。
2. 查看虚拟路径
poetry env info -p
3. 激活虚拟环境
# 激活虚拟环境
source $(poetry env info -p)/bin/activate
# 如果当前没有虚拟环境,可创建虚拟环境
poetry shell
# 此时可以使用 python 命令来运行 python 脚本,无需使用 poetry run 命令
python xxx.py
# 退出虚拟环境
deactivate