Python开发软件一般会涉及到发布, 部署的问题。常见的做法有2种, 1) 直接组织成代码文件目录的package, 将代码文件目录进行分发部署;2)编写 setup.py 安装脚本, 将开发的软件打包成标准包格式, 早期是 egg, 现在几乎都替换成 wheel 格式, 然后发布打包好的软件包, 参考官方文档 。
如果是用直接用代码目录组织的package, 例如 Django APP 开发, 通常我们可以使用pipenv 。
如果通过打包的方式, 可以选择使用官方的 distutils, 将依赖包写到 setup.py 脚本中, 基本满足绝大部分需求, 但是对于严谨的项目, 可能会遇到两个问题:
1) 依赖包需要手动维护, 且难以维护次级依赖包, 比如, 在开发阶段安装了pandas==0.20, 开发环境的次级依赖numpy==1.14, , 两个月后发布到生产环境时, 由于安装脚本没有主动指定numpy版本号, 极有可能生产环境安装了numpy==1.15。
2) 软件包升级需要开发者手动更新, 如果依赖较多, 那么需要开发者逐个确认依赖关系, 比如升级pandas包, 那么需要检查其下级依赖的numpy是否也需要升级, 而numpy升级是否又会影响当前其他一级依赖包。
基于这两个原因, 有必要在项目中使用 pipenv 和 poetry 这样的工具, pipenv太类似npm的风格, 个人不是很推崇, 而且对打包方式分发部署并不友好, 主要目标对象还是通过目录包的方式分发部署的应用。而poetry能够同时胜任两种开发场景, api设计和使用方式也很值得应用到项目中。
Poetry 的官方文档地址: https://python-poetry.org/docs/ , 下面列出一些常见的使用场景。
- 安装poetry: pip install poetry
- 用poetry创建新项目: poetry new my-project # 默认package路径是 ./my_project
- 或者在已有的项目目录中初始化poetry: poetry init # 根据提示设置项目信息
- 添加依赖包: poetry add pendulum
- 从git地址添加依赖包: poetry add git+https://github.com/sdispater/pendulum.git
- 从本地添加本地依赖包: poetry add ./dependencies/pendulum.whl
- 为添加的依赖包指定 extra option: poetry add "requests[security,socks]"
- 添加本地目录为作为开发依赖包(只作用于部署开发环境): poetry add --dev ./
- 删除一个依赖包: poetry remove pendulum
- 打包项目: poetry build, 打包结果存储在dist目录下
- 打印项目中的所有依赖包: poetry show
- 更新依赖包到最新版本: poetry update
需要注意的是, 国内执行 poetry add 可能会非常慢, 长时间卡在 "Resolving dependencies" , 可能跟国内的网络环境有关。建议遇到此类情况使用 poetry add -vvv lib-name 进入debug模式添加依赖包。 解决方案可以考虑配置国内阿里云镜像源到 pyproject.toml 中,配置方式参考 官方文档 :
[[tool.poetry.source]] name = "aliyun" url = "https://mirrors.aliyun.com/pypi/simple/"
添加配置后切记要运行 poetry update ,否则新添加的源不会生效。
在开发环境中, python setup.py develop 或者 pip install -e . 可以将正在开发的package包链接到系统环境, 开发调试非常方便。 poetry install 是等效命令, 而 poetry build 后安装dist目录的whl包则等效于``pip install .``或者``python setup.py install``。
自定义项目中的package配置, 例如为一个build安装多个package包:
[tool.poetry] packages = [ {include = "my_project"}, {include = "my_package"}, # 安装多个packages ]
同样的方式实现 namespace package :
[tool.poetry] packages = [ { include = 'my_package/sub_package' }, ]
更多详细配置: https://python-poetry.org/docs/pyproject/#packages。
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.