foril@blog ~
  __            _ _ 
 / _| ___  _ __(_) |
| |_ / _ \| '__| | |
|  _| (_) | |  | | |
|_|  \___/|_|  |_|_|
// developer & blogger
💻theme: auto
[░░░░░░░░░░░░░░░░░░░░] 0%

Python wheels

📅 2023-11-21|⏱ ~5 min read|#开发小记

##sdist 与 bdist

在使用 pip 安装某些包时,我们往往会看到这样的提示:

sh
$ python -m pip install 'uwsgi==2.0.*' Collecting uwsgi==2.0.* Downloading uwsgi-2.0.18.tar.gz (801 kB) |████████████████████████████████| 801 kB 1.1 MB/s Building wheels for collected packages: uwsgi Building wheel for uwsgi (setup.py) ... done Created wheel for uwsgi ... uWSGI-2.0.18-cp38-cp38-macosx_10_15_x86_64.whl Stored in directory: /private/var/folders/jc/8_hqsz0x1tdbp05 ... Successfully built uwsgi Installing collected packages: uwsgi Successfully installed uwsgi-2.0.18
  • 在第 3 行,它下载了一个名为 uwsgi-2.0.18.tar.gz 的 TAR 文件(tarball),该文件是用 gzip 压缩过的。
  • 在第 6 行,它接受 tarball 并通过调用 setup.py 构建一个 .whl 文件。
  • 在第 7 行,它将 wheel 标记为 uWSGI-2.0.18-cp38-cp38-macosx_10_15_x86_64.whl
  • 在第 10 行,它在构建 wheel 之后安装实际的包。

这里的 .tar.gz 文件就是 Source Distribution(sdist)。

如果我们查看 Pypi 上的 uWSGI 下载文件 ,我们可以看到它只有 Source Distribution:

uWSGI_pypi

Source Distribution 包含源代码,不仅包括 Python 代码,还包括与包捆绑在一起的任何扩展模块(通常是 C 或 C++ 语言)的源代码。对于 sdist,一些扩展模块是在用户端而不是开发人员端编译的。

而对于一些有 wheel 包的包,我们可以看到它有 Source Distribution 和 Built Distribution:

chardet_pypi

这里的 .whl 文件就是 Built Distribution(bdist),如果使用 pip 安装也可以看出明显不同:如果有合适的 wheel 包,pip 会直接安装 wheel 包,而不是下载源代码分发包(source distribution)然后在本地编译它。

sh
$ python -m pip install 'chardet==3.*' Collecting chardet Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB) |████████████████████████████████| 133 kB 1.5 MB/s Installing collected packages: chardet Successfully installed chardet-3.0.4

如果使用 pip 安装 Python 包时没有找到对应平台的预编译 wheel 文件,pip 通常会回退到下载源代码分发包(source distribution),然后在本地编译。

##什么是 wheel

Python .whl 文件本质上是一个 ZIP (.ZIP) 归档文件,带有一个特制的文件名,告诉安装程序 wheel 将支持哪些 Python 版本和平台。

wheel 是一种 bdist。意味着 wheel 可以随时被安装,并允许跳过 sdist 所需的构建阶段。

wheel 的命名规则

wheel文件名被分解成用连字符分隔的部分:

code
{dist}-{version}(-{build})?-{python}-{abi}-{platform}.whl 比如 cryptography-2.9.2-cp35-abi3-macosx_10_9_x86_64.whl
  • Cryptography 是包名。

  • 2.9.2 是密码学的包版本。版本是符合 PEP 440 的字符串,如 2.9.23.43.9.0.3.a3

  • cp35 是 Python 标签,表示 wheel 所需的 Python 实现和版本。cp 代表 CPython, Python 的参考实现,而 35 表示 Python 3.5。例如,这个轮子与 Jython 不兼容。

  • abi3 是 ABI 标记。ABI 代表应用程序二进制接口。实际上不需要担心它需要什么,但是 abi3 是 Python C API 的二进制兼容性的单独版本。

  • Macosx_10_9_x86_64 是平台标记,它很拗口。在这种情况下,它可以进一步细分为子部分:

    • macosx 是 macOS 操作系统。
    • 10_9 是 macOS developer tools SDK 版本,用于编译 Python,从而构建此 wheel。
    • x86_64 是对 x86-64 指令集体系结构的引用。

##wheel 的优势

  • 对于纯 Python 包和扩展模块,wheels 的安装速度都比源代码发行版快。
  • 比 sdist小。
  • 车轮排除了 setup.py 的影响,不需要运行 setup.py
  • 不需要编译器。
  • pip 会自动在 wheel 中生成匹配正确 Python 解释器的 .pyc 文件。
  • 车轮提供了一致性(比如排除了变量的影响)。

##参考

$ tree --headings