1. Distutils 简介 — Python 文档
1. Distutils 简介
笔记
本文档仅保留到 https://setuptools.readthedocs.io/en/latest/setuptools.html 上的 setuptools
文档独立涵盖当前包含在此处的所有相关信息之前。
本文档涵盖使用 Distutils 分发 Python 模块,重点介绍开发人员/分发者的角色:如果您正在寻找有关安装 Python 模块的信息,您应该参考 安装 Python 模块(旧版)[X262X ] 章节。
1.1. 概念和术语
使用 Distutils 非常简单,对于模块开发人员和安装第三方模块的用户/管理员来说都是如此。 作为开发人员,您的职责(当然,除了编写可靠、有据可查和经过充分测试的代码!)是:
- 编写一个安装脚本(按照惯例
setup.py
) - (可选)编写设置配置文件
- 创建源分发
- (可选)创建一个或多个构建的(二进制)发行版
本文档涵盖了这些任务中的每一个。
并非所有模块开发人员都可以访问多种平台,因此期望他们创建多种构建的发行版并不总是可行的。 希望出现一类称为 包装器 的中介来满足这一需求。 打包者将采用模块开发者发布的源代码分发,在一个或多个平台上构建它们,并发布生成的构建分发。 因此,最流行平台上的用户将能够以最自然的方式为其平台安装最流行的 Python 模块发行版,而无需运行单个安装脚本或编译一行代码。
1.2. 一个简单的例子
设置脚本通常非常简单,尽管由于它是用 Python 编写的,因此您可以用它做什么没有任何限制,但您应该小心在设置脚本中放置任意昂贵的操作。 与 Autoconf 风格的配置脚本不同,安装脚本可能会在构建和安装模块分发的过程中多次运行。
如果您只想分发一个名为 foo
的模块,该模块包含在文件 foo.py
中,那么您的安装脚本可以像这样简单:
from distutils.core import setup
setup(name='foo',
version='1.0',
py_modules=['foo'],
)
一些观察:
- 您提供给 Distutils 的大多数信息都作为关键字参数提供给
setup()
函数 - 这些关键字参数分为两类:包元数据(名称、版本号)和有关包中内容的信息(在本例中为纯 Python 模块列表)
- 模块由模块名称指定,而不是文件名(包和扩展名也是如此)
- 建议您提供更多元数据,尤其是您的姓名、电子邮件地址和项目的 URL(请参阅 编写安装脚本 部分以获取示例)
要为此模块创建源代码分发版,您需要创建一个包含上述代码的安装脚本 setup.py
,然后从终端运行以下命令:
python setup.py sdist
对于 Windows,打开命令提示符窗口 (
) 并将命令更改为:setup.py sdist
sdist 将创建一个存档文件(例如,Unix 上的 tarball,Windows 上的 ZIP 文件),其中包含您的安装脚本 setup.py
和您的模块 foo.py
。 存档文件将命名为 foo-1.0.tar.gz
(或 .zip
),并将解压到目录 foo-1.0
。
如果最终用户希望安装您的 foo
模块,他们所要做的就是下载 foo-1.0.tar.gz
(或 .zip
),解压缩,然后——从 foo-1.0
目录——运行
python setup.py install
最终将 foo.py
复制到 Python 安装中第三方模块的相应目录。
这个简单的例子展示了 Distutils 的一些基本概念。 首先,开发者和安装者都有相同的基本用户界面,即 安装脚本。 不同之处在于他们使用哪些 Distutils commands:sdist 命令几乎专供模块开发人员使用,而 install 命令更常用于安装程序(尽管大多数开发人员会想要偶尔安装自己的代码)。
如果您想让用户的工作变得非常简单,您可以为他们创建一个或多个构建的发行版。 例如,如果您在 Windows 机器上运行,并且想让其他 Windows 用户更轻松,您可以使用 bdist_wininst 创建一个可执行安装程序(最适合该平台的构建分发类型)命令。 例如:
python setup.py bdist_wininst
将在当前目录中创建一个可执行安装程序 foo-1.0.win32.exe
。
其他有用的构建分发格式是 RPM,由 bdist_rpm 命令、Solaris pkgtool (bdist_pkgtool) 和 HP-UX swinstall ( bdist_sdux)。 例如,以下命令将创建一个名为 foo-1.0.noarch.rpm
的 RPM 文件:
python setup.py bdist_rpm
(bdist_rpm 命令使用 rpm 可执行文件,因此它必须在基于 RPM 的系统上运行,例如 Red Hat Linux、SuSE Linux 或 Mandrake Linux。)
您可以通过运行随时了解可用的分发格式
python setup.py bdist --help-formats
1.3. 通用 Python 术语
如果您正在阅读本文档,您可能对什么是模块、扩展等有一个很好的了解。 尽管如此,为了确保每个人都从一个共同的起点进行操作,我们提供了以下常用 Python 术语的词汇表:
- 模块
- Python 中代码可重用性的基本单元:由其他代码导入的代码块。 我们在这里关注三种类型的模块:纯 Python 模块、扩展模块和包。
- 纯 Python 模块
- 一个用 Python 编写并包含在单个
.py
文件(以及可能关联的.pyc
文件)中的模块。 有时称为“纯模块”。 - 扩展模块
- 用 Python 实现的低级语言编写的模块:C/C++ for Python,Java for Jython。 通常包含在单个可动态加载的预编译文件中,例如 Unix 上 Python 扩展的共享对象 (
.so
) 文件、Windows 上 Python 扩展的 DLL(给定.pyd
扩展)或 Jython 扩展的 Java 类文件。 (请注意,目前,Distutils 仅处理 Python 的 C/C++ 扩展。) - 包裹
- 一个包含其他模块的模块; 通常包含在文件系统的目录中,并通过文件
__init__.py
的存在与其他目录区分开来。 - 根包
- 包层次结构的根。 (这不是一个真正的包,因为它没有
__init__.py
文件。 但我们必须对其进行命名。)绝大多数标准库都在根包中,许多不属于较大模块集合的小型独立第三方模块也是如此。 与常规包不同,根包中的模块可以在许多目录中找到:实际上,sys.path
中列出的每个目录都为根包贡献了模块。
1.4. Distutils 特定术语
以下术语更具体地适用于使用 Distutils 分发 Python 模块的领域:
- 模块分布
- 一组 Python 模块作为单个可下载资源分布在一起,旨在 整体安装 。 一些众所周知的模块分布的例子是 NumPy、SciPy、Pillow 或 mxBase。 (这将被称为 包 ,但该术语已在 Python 上下文中使用:单个模块分发可能包含零个、一个或多个 Python 包。)
- 纯模块分布
- 仅包含纯 Python 模块和包的模块分发版。 有时也称为“纯分布”。
- 非纯模块分布
- 包含至少一个扩展模块的模块分布。 有时也称为“非纯分布”。
- 分布根
- 源代码树(或源代码分发)的顶级目录;
setup.py
所在的目录。 通常setup.py
将从这个目录运行。