7. Examples

本章提供了一些基本示例,以帮助您开始使用 distutils。有关使用 distutils 的其他信息,请参见 Distutils Cookbook。

See also

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'],
      )

请注意,发行版的名称是passname选项独立指定的,没有规则说该名称必须与发行版中唯一模块的名称相同(尽管遵循的惯例可能不错)。但是,分发名称用于生成文件名,因此您应坚持字母,数字,下划线和连字符。

由于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'],
      )

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

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 不会*扫描您的源代码树,而是pass查找__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

如果fooextensions 属于根软件包,则此安装脚本可能是

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

如果 extensions 实际上属于某个包,请说foopkg,然后

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

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