1. Distutils 模块介绍
*********************

備註:

  这篇文档只有在
  https://setuptools.readthedocs.io/en/latest/setuptools.html 上的
  "setuptools" 文档独立涵盖此处包含的所有相关信息之前，才会单独保留。

本文档介绍了使用 Distutils 模块分发你的 Python 模块，主要是针对开发者/
分发者的使用的——如果你想了解如何安装 Python 模块，你应该参考这个章节：
安裝 Python 模組（舊版）。


1.1. 概念和术语
===============

Distutils 用起来非常简单，对于模块开发者或安装第三方模块的用户/管理员
均是如此。开发者的责任（当然还有编写可靠、良好文档和经过良好测试的代码
！）就是：

* 编写一个设置脚本 ("setup.py" by convention)

* (可选)编写设置脚本的配置文件

* 创建源码的发行版

* （可选）创建一个或多个编译好（二进制）的发行版

每个这些任务均已在此文档覆盖.

并非所有的模块开发者都能接触到众多的平台，所以期望他们创造众多的内置发
行版不是总是可行的。最好是有一类名为 *打包者* 的中介，以满足这一需求。
打包者将读取模块开发者发布的源代码，在一个或多个平台上进行编译，并发布
构建出来的发行版。这样，最流行平台的用户就能以最自然的方式安装最流行的
Python 模块发行版，不必运行什么设置脚本或编译代码了。


1.2. 一个简单的例子
===================

setup 脚本通常很简单，尽管是用 Python 编写的，它能干的事情没有限制，当
然应小心别在 setup 脚本中加入什么运行缓慢的操作。与 Autoconf 风格的
configure 脚本不同，在构建和安装模块的过程中 setup 脚本可能会被多次运
行。

如果只想发布一个名为 "foo" 的模块，位于 "foo.py" 文件中，那么 setup 脚
本可以如此简单：

   from distutils.core import setup
   setup(name='foo',
         version='1.0',
         py_modules=['foo'],
         )

一些观察:

* 提供给 Distutils 的大部分信息将作为关键字参数发给 "setup()" 函数。

* 这些关键字参数分为两类：包的元数据（名称、版本号）和包中内容的描述信
  息（本例中是纯 Python 模块的列表）。

* 模块由模块名指定，而不是文件名（包和扩展也是如此）。

* 建议多提供一些元数据，特别是开发者姓名、电子邮件地址和项目的URL（参
  见 编写安装脚本 中的例子）。

要为该模块创建一个源码发布版本，需要创建一段 setup 脚本 "setup.py"，包
含上述代码，然后从终端运行以下命令：

   python setup.py sdist

Windows用户, 打开命令行窗口 (Start ‣ Accessories) 并且更改命令为:

   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 的一些基本概念。首先，开发者和安装者拥有
相同的基本用户界面，即 setup 脚本。区别在于使用哪种 Distutils *命令*
： **sdist** 命令几乎只适用于模块开发者，而 **install** 则更适用于安装
者（当然大多数开发者偶尔也想要安装自己的代码）。

If you want to make things really easy for your users, you can create
one or more built distributions for them.  For instance, if you are
running on a Windows machine, and want to make things easy for other
Windows users, you can create an executable installer (the most
appropriate type of built distribution for this platform) with the
**bdist_wininst** command.  For example:

   python setup.py bdist_wininst

will create an executable installer, "foo-1.0.win32.exe", in the
current directory.

其他有用的内置分发格式是 RPM，可由 **bdist_rpm** 、Solaris **pkgtool`
（:command:`bdist_pkgtool**）和 HP-UX **swinstall`（
:command:`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 常用术语表：

module
   实现 Python 代码重用的基本单位：可被其他代码导入的一段代码。有三种
   类型的模块与本文有关：纯 Python 模块、扩展模块和包。

纯 Python 模块
   用 Python 编写的模块，包含在某 ".py" 文件中（可能还会有相关的
   ".pyc" 文件）。有时被称为 "纯模块"。

extension module -- 扩展模块
   用低级语言编写的  Python 模块。Python 用 C/C++ ，而 Jython 则用Java
   。通常包含在一个可动态加载的预编译文件中，比如 Unix 中的 Python 扩
   展是一个共享对象（".so"）文件，Windows 中的 Python 扩展则是一个 DLL
   （扩展名为 ".pyd" )，而 Jython 的扩展是个 Java class 文件。（注意，
   目前，Distutils 只能处理 Python 的 C/C++ 扩展。）

package -- 包
   包含其他模块的模块；通常位于文件系统的某个目录中，区别于其他目录的
   标记就是存在一个  "__init__.py" 文件。

根包
   包的层次结构的根。（其并非一个真正的包，因为没有 "__init__.py" 文件
   。但总得给它起个名字）。 绝大多数标准库都在根包中，还有许多不属于任
   何大型模块的小型、独立的第三方模块。与普通的包不同，根包中的模块可
   能会在很多目录中出现：事实上，"sys.path" 列出的每个目录都会为根包提
   供模块。


1.4. Distutils 特定的术语
=========================

以下属于更加特别地用于 Distutils 发布 Python 模块。

模块的发布
   一组 Python 模块，作为可下载的资源组团发布，以便 *大规模* 安装。模
   块发布版的著名例子是 NumPy 、 SciPy 、 Pillow 或 mxBase。（这些会被
   称为 *package*，这个词在 Python 的语境中也使用过：一个模块发行版可
   能包含零个、一个或多个 Python 包。)

纯模块发行版
   只包含纯 Python 模块和软件包的模块发布版。有时被称为“纯发行版”。

非纯模块发行版
   至少包含一个扩展模块的模块发行版。 有时被称为“非纯发行版”。

根发行版
   源代码树（或源代码发行版）的顶级目录；即 "setup.py" 所在的目录。 一
   般来说，"setup.py" 会在该目录下运行。
