【问题标题】:Can I define optional packages in setuptools?我可以在 setuptools 中定义可选包吗?
【发布时间】:2012-06-29 17:11:01
【问题描述】:

目前我的一个包需要一个 JSON 解析器/编码器,并且设计为使用 simplejson,如果有必要的话,可以回退到 json 模块(在标准库中)(因为基准测试显示 simplejson 更快)。

然而,最近关于simplejson 是否会在使用zc.buildout 时安装的问题屡见不鲜——我相信这是迁移到 github 的事情。这让我想知道;是否可以在我的 setup.py 文件中定义可选包,如果不可用,不会停止我的包的安装?

【问题讨论】:

    标签: python setuptools


    【解决方案1】:

    AFAIK 没有办法定义可选包,这样做也没有用。当您定义一个可选包时,您期望什么?它是在它还不可用时安装的吗? (这会以某种方式使其成为强制性)

    不,恕我直言,解决此问题的正确方法是在您要使用包的导入中。例如:

    try:
        from somespecialpackage import someapi as myapi
    except ImportError:
        from basepackage import theapi as myapi
    

    这当然要求两个 API 兼容,但 simplejson 和标准库 json 包就是这种情况。

    【讨论】:

    • 可选意味着如果包安装失败,安装可以畅通无阻地完成。
    • 好的,但是如果你不非常依赖一个包,为什么还要把它放在必需的包中呢?我只是不明白这一点。
    • 我不想放到required列表中;这就是我要问的 - 是否有其他选项,如果可用,我可以将其包含在内,但如果没有,则忽略?
    • 因为可能存在模仿行为并且难以在某些平台上构建的 C 优化库。这有助于开发,特别是如果您使用的是非基于 *nix 的操作系统。
    【解决方案2】:

    安装时的可选包。

    我假设您正在谈论您的 setup.py 脚本。 您可以将其更改为:

    # mypackage/setup.py
    
    extras = {
       'with_simplejson': ['simplejson>=3.5.3']
    }
    
    setup(
        ...
        extras_require=extras,
        ...)
    

    那么您可以执行以下任一操作:

    • pip install mypackage,
    • pip install mypackage[with_simplejson]

    后者安装simplejson>=3.5.3

    与其尝试安装所有内容并回退到已知的良好版本, 你会想要安装你知道可以工作的包的子集。

    执行时的可选包。

    一旦你有两组不同的软件包可以安装,你需要 确保您可以使用它们(如果它们可用)。例如。为您的json 导入:

    try:
        # helpful comment saying this should be faster.
        import simplejson as json
    except ImportError:
        import json
    

    另一个更复杂的例子:

    try:
        # xml is dangerous
        from defusedxml.cElementTree import parse
    except ImportError:
        try:
            # cElementTree is not available in older python
            from xml.cElementTree import parse
        except ImportError:
            from xml.ElementTree import parse
    

    但您也可以在某些包中找到这种模式:

    try:
        optional_package = None
        import optional.package as optional_package
    except ImportError:
        pass
    
    ...
    
    if optional_package:
        # do addtional behavior
    

    【讨论】:

    • 对可选要求的实际代码内含义的非常有用的讨论 - 另一种方法是在函数内部进行一些导入,并在完全使用特定代码路径时从那里引发异常(建议什么在错误消息中安装)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2019-04-12
    • 2011-04-03
    • 2015-10-02
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    相关资源
    最近更新 更多