PEP 8 和延迟导入

PEP 8 and deferred import

我正在开发一个大型 Python 程序,该程序根据命令行选项使用大量模块,特别是 numpy。我们最近发现需要在一个小型嵌入式模块上 运行 这排除了 numpy 的使用。从我们的角度来看,这很容易(只是不要使用有问题的命令行选项。)

但是,在PEP 8之后,我们的import numpy在每个可能需要它的模块的开头,程序会因为numpy没有安装而崩溃。直接的解决方案是将 import numpy 从文件顶部移动到需要它的函数。问题是,"How bad is this"?

(另一种解决方案是将 import numpy 包装在 try .. except 中。这样更好吗?)

这是一个最佳实践模式,用于检查模块是否已安装并根据它创建代码分支。

# GOOD
import pkg_resources

try:
    pkg_resources.get_distribution('numpy')
except pkg_resources.DistributionNotFound:
    HAS_NUMPY = False
else:
    HAS_NUMPY = True
    # You can also import numpy here unless you want to import it inside the function

在每个对 numpy 具有软依赖性的模块导入中执行此操作。 More information in Plone CMS coding conventions.

我见过的另一个习惯用法是,如果不可用,将模块导入为 None:

try:
    import numpy as np
except ImportError:
    np = None

或者,, you can use the pkg_resources.get_distribution above, rather than try/except (see the blog post linked to from the plone docs).

这样,在使用 numpy 之前,您可以在 if 块中隐藏 numpy 的使用:

if np:
     # do something with numpy
else:
     # do something in vanilla python

key 是为了确保你的 CI 测试有两种环境——有和没有 numpy(如果你正在测试覆盖率,这应该将两个块都算作覆盖) .