1+1=10

记记笔记,放松一下...

Python打包与包管理小记

记忆力似乎越来越差,简单记一下

历史

Python 包管理和打包技术经历了多个阶段的发展,从早期的简单手动分发到现代的 .whl 格式和 pip 工具。

手动分发阶段(2000年代初期及之前)

最初,Python 包的分发和安装都是手动进行的,需要下载源代码并运行 setup.py 脚本来安装。

2000年9月,Python1.6的标准库引入了 distutils 模块,使打包和分发 Python 模块更为规范。 但 distutils 功能有限,对依赖关系管理能力较弱,扩展性不足。

setuptools 和 .egg 格式(2004 年)

Philip J. Eby 在 2004 年发布了 setuptools 模块。 distutils 的扩展,增加了更强大的功能,如依赖管理和插件支持。

setuptools 引入了统一的 .egg 包格式以及安装工具 easy_install

  • .egg 格式:提供了包的归档和分发方式。包中包含代码和元数据,支持即用即装。
  • easy_install:用于安装和管理 .egg 包。简化了安装。

easy_install依赖管理较弱,难以处理复杂依赖。

pip 和 virtualenv(2008 年)

pip 于 2008年发布,它由 Ian Bicking 开发。相较于 easy_installpip 提供了更强大的依赖管理、卸载功能。

virtualenv 提供了一个工具来创建独立的 Python 环境,使开发者能够为每个项目创建隔离的环境,避免不同项目之间的依赖冲突。它由 Ian Bicking 和 Chris B. Wilson 等人开发,并在 2007 年发布。

2011年pip 0.3版本引入 pip freeze 。用于生成当前环境中安装的所有包和版本的列表,通常用于创建 requirements.txt 文件,这对于项目的依赖管理和环境重建非常有用。

.whl格式(2012 年)

.whl 格式由 PEP 427 引入,成为标准化的打包格式。目的是克服 .egg 的缺陷,如兼容性问题和社区支持不足。

.whl 文件可直接安装,无需编译,安装速度快,与 pip 完全集成。setuptools 继续用于构建包,但打包输出格式支持 .whl

pip 1.4 发布于2013年,提供了 .whl的全面支持。而后 .egg 逐渐不受待见。

build 与 pyproject.toml(2018)

PEP 517 和 PEP 518 引入了新的构建系统接口,允许项目定义自定义构建后端,如 poetryflit,提升了打包和构建的灵活性。

pyproject.toml 文件成为了现代 Python 项目的标准配置文件,允许项目声明构建系统、依赖项以及其他相关元数据。

build 遵循 PEP 517 规范而设计的工具。build 提供了一个轻量级且标准化的方式来构建 .whl 和 .tar.gz 文件

使用举例

生成 .whl 包

有多种方式可以生成 .whl 包

使用 setuptools + wheel(已不推荐)

尽管(曾)是最常见的打包方式,但已经不被推荐使用,见:

首先安装依赖

1
pip install setuptools wheel

确保存在 setup.py 文件:

1
2
3
4
5
6
7
8
from setuptools import setup, find_packages

setup(
    name="my_package",
    version="0.0.1",
    packages=find_packages(),
    # more ...
)

生成.whl包

1
python setup.py sdist bdist_wheel

尽管这个方式不被推荐,但并不是说 setup.py 已经被取缔。只是建议不要这么直接调用它!!所以,下面的 build 继续在用它

使用 build 工具

首先安装依赖

1
pip install build

生成 .whl 文件

1
python -m build

使用flit工具

安装依赖:

1
pip install filt

生成

1
filt build

发布到 pypi

注册账户

注意,测试网站账户和正式的pypi账户不互通,需要分别注册。

配置 .pypirc

配置用户配置文件 ~/.pypirc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = <my-api-token-here>

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = <my-api-token-here>

其中,api koken在网站上生成。

twine 上传

安装

1
pip install twine

上传 dist/ 下的所有文件

1
twine upload dist/*

如果要上传到test,需要使用

1
twine upload --repository testpypi dist/*

参考资料

Python