7. 示例 — Python 文档

来自菜鸟教程
Python/docs/2.7/distutils/examples
跳转至:导航、​搜索

7. 例子

本章提供了许多基本示例来帮助开始使用 distutils。 有关使用 distutils 的其他信息可以在 Distutils Cookbook 中找到。

也可以看看

Distutils 食谱
展示如何更好地控制 distutils 的食谱集。


7.1. 纯 Python 发行版(按模块)

如果您只是分发几个模块,特别是如果它们不在特定包中,则可以使用安装脚本中的 py_modules 选项单独指定它们。

在最简单的情况下,您需要担心两个文件:一个安装脚本和您分发的单个模块,在本例中为 foo.py

<root>/
        setup.py
        foo.py

(在本节的所有图表中,' 将引用分发根目录。)描述这种情况的最小安装脚本是:

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

请注意,发行版的名称是用 name 选项独立指定的,并且没有规定它必须与发行版中唯一模块的名称相同(尽管这可能是一个很好的约定跟随)。 但是,分发名称用于生成文件名,因此您应该坚持使用字母、数字、下划线和连字符。

由于 py_modules 是一个列表,您当然可以指定多个模块,例如。 如果您分发模块 foobar,您的设置可能如下所示:

<root>/
        setup.py
        foo.py
        bar.py

安装脚本可能是

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

您可以将模块源文件放到另一个目录中,但是如果您有足够的模块来执行此操作,那么按包指定模块可能比单独列出它们更容易。


7.2. 纯 Python 发行版(按包)

如果您有多个模块要分发,特别是如果它们位于多个包中,则指定整个包而不是单个模块可能更容易。 即使您的模块不在包中,这也有效; 你可以告诉 Distutils 从根包处理模块,这与任何其他包的工作方式相同(除了你不必有 __init__.py 文件)。

上一个例子中的设置脚本也可以写成

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

(空字符串代表根包。)

如果这两个文件被移动到一个子目录中,但保留在根包中,例如:

<root>/
        setup.py
        src/      foo.py
                  bar.py

那么你仍然会指定根包,但你必须告诉 Distutils 根包中的源文件所在的位置:

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'': 'src'},
      packages=[''],
      )

但是,更常见的是,您希望在同一个包(或子包)中分发多个模块。 例如,如果 foobar 模块属于包 foobar,则布局源树的一种方法是

<root>/
        setup.py
        foobar/
                 __init__.py
                 foo.py
                 bar.py

这实际上是 Distutils 所期望的默认布局,并且在您的安装脚本中需要最少的工作来描述:

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

如果您想将模块放在未以其包命名的目录中,则需要再次使用 package_dir 选项。 例如,如果 src 目录包含 foobar 包中的模块:

<root>/
        setup.py
        src/
                 __init__.py
                 foo.py
                 bar.py

一个合适的安装脚本是

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'foobar': 'src'},
      packages=['foobar'],
      )

或者,您可以将主包中的模块直接放在分发根目录中:

<root>/
        setup.py
        __init__.py
        foo.py
        bar.py

在这种情况下,您的安装脚本将是

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'foobar': ''},
      packages=['foobar'],
      )

(空字符串也代表当前目录。)

如果您有子包,它们必须在 packages 中明确列出,但 package_dir 中的任何条目都会自动扩展到子包。 (换句话说,Distutils 不会 扫描你的源代码树,试图通过查找 __init__.py 文件来找出对应于 Python 包的目录。)因此,如果默认布局增长了子包:

<root>/
        setup.py
        foobar/
                 __init__.py
                 foo.py
                 bar.py
                 subfoo/
                           __init__.py
                           blah.py

那么相应的安装脚本将是

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=['foobar', 'foobar.subfoo'],
      )

7.3. 单扩展模块

使用 ext_modules 选项指定扩展模块。 package_dir 对找到扩展源文件的位置没有影响; 它只影响纯 Python 模块的源代码。 最简单的情况,单个 C 源文件中的单个扩展模块是:

<root>/
        setup.py
        foo.c

如果 foo 扩展属于根包,则此安装脚本可能是

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )

如果扩展实际上属于一个包,比如 foopkg,那么

使用完全相同的源代码树布局,只需更改扩展名,即可将此扩展放入 foopkg 包中:

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
      )