setup.py 添加选项(即 setup.py --enable-feature)

4 投票
2 回答
3062 浏览
提问于 2025-04-15 22:00

我想在安装阶段给一个Python(扩展)模块添加一些功能。

具体来说:

我有一个Python库,这个库里面有两个实现同一个功能的方法,一个是内部的(比较慢),另一个是依赖外部库的(比较快,用C语言写的)。

我希望这个外部库是可选的,并且可以在编译/安装的时候通过一个标志来激活,比如:

python setup.py install # (it doesn't include the fast library)
python setup.py --enable-fast install

我必须使用Distutils,不过其他的解决方案也都可以接受!

2 个回答

4

distutils的文档里有一部分内容讲的是如何扩展标准功能,具体可以查看这段说明。相关的建议是,你可以从distutils.command.*模块中找到相关的类(比如build_pyinstall),然后创建这些类的子类。接着,你需要告诉setup使用你新创建的版本,这可以通过cmdclass这个参数来实现,它是一个字典,用来把命令和对应的类关联起来,以便执行这些命令。想要了解如何添加新选项,可以查看任何命令类的源代码(例如install命令的代码),这样你就能清楚需要做些什么了。

2

你想要的例子就是sqlalchemycextensions,这些扩展正是为了加快速度而设计的C语言实现。要了解sqlalchemy是怎么实现的,你需要查看两个文件:

1) setup.py。从下面的摘录可以看到,他们是如何处理setuptoolsdistutils的:

try:
    from setuptools import setup, Extension, Feature
except ImportError:
    from distutils.core import setup, Extension
    Feature = None

之后会有一个检查if Feature:,然后根据不同的情况,使用变量extra来正确配置扩展,这个变量最后会被添加到setup()函数中。

2) base.py:在这里查看BaseRowProxy是如何定义的:

try:
    from sqlalchemy.cresultproxy import BaseRowProxy
except ImportError:
    class BaseRowProxy(object):
        #....

所以基本上,一旦安装了C扩展(在设置时使用--with-cextensions标志),就会使用C语言实现。否则,就会使用纯Python的实现。

撰写回答