28

我有一个名为“example”的库,正在安装到我的全局站点包目录中。但是,我希望能够安装两个版本,一个用于生产,一个用于测试(我有一个 Web 应用程序和其他以这种方式进行版本控制的东西)。

有没有办法指定,比如“python setup.py stage”,它不仅可以将不同的鸡蛋安装到站点包中,还可以将模块从“example”重命名为“example_stage”或类似的东西?

如果 distutils 不能做到这一点,还有其他工具可以做到吗?

4

4 回答 4

56

这可以通过在 setup.py中子类distutils.core.Command使用 distutils 轻松完成。

例如:

from distutils.core import setup, Command
import os, sys

class CleanCommand(Command):
    description = "custom clean command that forcefully removes dist/build directories"
    user_options = []
    def initialize_options(self):
        self.cwd = None
    def finalize_options(self):
        self.cwd = os.getcwd()
    def run(self):
        assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd
        os.system('rm -rf ./build ./dist')  

要启用该命令,您必须在 setup() 中引用它:

setup(
     # stuff omitted for conciseness.
     cmdclass={
        'clean': CleanCommand
}

请注意,您也可以通过这种方式覆盖内置命令,例如我使用 'clean' 所做的。(我不喜欢内置版本如何留下 'dist' 和 'build' 目录。)

% python setup.py --help-commands | grep clean
  clean            custom clean command that forcefully removes dist/build dirs.

使用了许多约定:

  • 您可以使用user_options指定任何命令行参数。
  • 您声明将与initialize_options()方法一起使用的任何变量,该方法在初始化后调用以设置子类的自定义命名空间。
  • finalize_options()方法在run()之前被调用。
  • 命令本身的内容将发生在run()中,因此请务必在此之前进行任何其他准备工作。

使用的最佳示例就是查看PYTHON_DIR/distutils/command中的默认命令之一的源代码,例如install.pybuild.py

于 2009-11-11T02:07:20.370 回答
14

当然,您可以使用新命令扩展 distutils。在您的 distutil 配置文件中,添加:

 [global]
 command-packages=foo.bar

这可以在distutils.cfgdistutils本身、..pydistutils.cfg您的主目录(Windows 上没有前导点)或setup.cfg当前目录中。

然后,您需要在 Python 的 site-packages 目录中有一个 foo.bar 包。

然后在该包中添加实现新所需命令的类,例如stage子类化distutils.cmd - 文档很弱,但有很多示例,因为所有现有的 distutils 命令也是以这种方式构建的。

于 2009-11-11T00:41:01.093 回答
5

如果您想使用多个版本,那么带有 virtualenvwrapper 的virtualenv可以提供帮助。

于 2009-11-10T21:14:38.520 回答
2

如果你想用 distutils 来做这件事,请参阅Alex 的回答,但我发现Paver更适合这种事情。它使自定义命令或覆盖现有命令变得更加容易。另外,如果您习惯使用 distutils 或 setuptools,过渡并不是非常困难。

于 2009-11-11T00:43:57.050 回答