目前,我的一个包需要一个 JSON 解析器/编码器,并且设计为在必要时使用(simplejson
如果有的话)回退到json
模块(在标准库中)(因为基准测试显示simplejson
更快)。
然而,最近它在使用时是否simplejson
会安装zc.buildout
- 我相信移动到 github 的问题。这让我想知道;是否可以在我的setup.py
文件中定义可选包,如果不可用,不会停止我的包的安装?
目前,我的一个包需要一个 JSON 解析器/编码器,并且设计为在必要时使用(simplejson
如果有的话)回退到json
模块(在标准库中)(因为基准测试显示simplejson
更快)。
然而,最近它在使用时是否simplejson
会安装zc.buildout
- 我相信移动到 github 的问题。这让我想知道;是否可以在我的setup.py
文件中定义可选包,如果不可用,不会停止我的包的安装?
我假设您正在谈论您的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
AFAIK 没有办法定义可选包,这样做也没有用。当您定义一个可选包时,您期望什么?它是在它还不可用时安装的吗?(这会以某种方式使其成为强制性的)
不,恕我直言,解决此问题的正确方法是在要使用该包的导入中。例如:
try:
from somespecialpackage import someapi as myapi
except ImportError:
from basepackage import theapi as myapi
这当然要求两个 API 兼容,但simplejson
标准库json
包就是这种情况。