SciPy API#

从 SciPy 导入#

在 Python 中,库的公共 API 和私有实现细节之间的区别并不总是很清楚。与其他语言(如 Java)不同,在 Python 中可以访问“私有”函数或对象。有时这可能很方便,但请注意,如果您这样做,您的代码可能会在未来的版本中突然崩溃,恕不另行通知。以下是一些关于 Python 中什么是公共的以及什么不是公共的广泛理解的规则:

  • 名称以一个前导下划线开头的方法/函数/类和模块属性是私有的。

  • 如果类名以一个前导下划线开头,则它的所有成员都不是公共的,无论它们是否以一个前导下划线开头。

  • 如果包中的模块名称以一个前导下划线开头,则它的所有成员都不是公共的,无论它们是否以一个前导下划线开头。

  • 如果模块或包定义了 __all__,则它权威地定义了公共接口。

  • 如果模块或包没有定义 __all__,则所有不以前导下划线开头的名称都是公共的。

注意

阅读以上指导原则,人们可能会得出结论,每个私有模块或对象都以下划线开头。事实并非如此;下划线的存在确实将某些东西标记为私有的,但缺少下划线并不将某些东西标记为公共的。

在 SciPy 中,有一些模块的名称不以下划线开头,但应该被认为是私有的。为了澄清这些模块是什么,我们在下面定义了 SciPy 的公共 API,并给出了一些关于如何从 SciPy 导入模块/函数/对象的建议。

从 SciPy 导入函数的指南#

SciPy 子模块命名空间中的所有内容都是公共的。通常在 Python 中,建议使用命名空间。例如,函数 curve_fit(在 scipy/optimize/_minpack_py.py 中定义)应该像这样导入:

import scipy
result = scipy.optimize.curve_fit(...)

或者,也可以像这样使用子模块作为命名空间:

from scipy import optimize
result = optimize.curve_fit(...)

注意

对于 scipy.io,最好使用 import scipy,因为 io 也是 Python stdlib 中模块的名称。

在某些情况下,公共 API 更深一层。例如,scipy.sparse.linalg 模块是公共的,它包含的函数在 scipy.sparse 命名空间中不可用。有时,如果从更深一层导入函数,可能会更容易理解代码。例如,在以下示例中,如果选择第二种形式,则可以立即清楚地知道 lomax 是一个分布:

# first form
from scipy import stats
stats.lomax(...)

# second form
from scipy.stats import distributions
distributions.lomax(...)

在这种情况下,可以选择第二种形式,**如果**在下一节中记录了相关子模块是公共的。当然,您仍然可以使用:

import scipy
scipy.stats.lomax(...)
# or
scipy.stats.distributions.lomax(...)

注意

SciPy 使用延迟加载机制,这意味着只有当您第一次尝试访问模块时,模块才会被加载到内存中。

API 定义#

下面列出的每个子模块都是公共的。这意味着这些子模块不太可能被重命名或以不兼容的方式更改,如果需要这样做,则会在更改前的一个 SciPy 版本中引发弃用警告。

SciPy 结构#

所有 SciPy 模块都应遵循以下约定。在下文中,*SciPy 模块*被定义为位于 scipy/ 目录中的 Python 包,例如 yyy

  • 理想情况下,每个 SciPy 模块都应尽可能地自包含。也就是说,它应该尽量减少对其他包或模块的依赖。即使对其他 SciPy 模块的依赖也应保持在最低限度。当然,假定对 NumPy 有依赖。

  • 目录 yyy/ 包含:

    • 一个文件 meson.build,其中包含子模块的构建配置。

    • 一个目录 tests/,其中包含与模块 yyy/<name>{.py,.so,/} 对应的文件 test_<name>.py

  • 私有模块应以前导下划线 _ 为前缀,例如 yyy/_somemodule.py

  • 用户可见的函数应具有遵循 NumPy 文档风格 的良好文档。

  • 模块的 __init__.py 的文档字符串中应包含主要的参考文档。这通过 Sphinx 的 automodule 指令连接到 doc/ 下的 Sphinx 文档。

    参考文档应首先使用 autosummary:: 指令给出模块内容的分类列表,然后解释理解模块用法所必需的要点。

    带有大量示例的教程式文档应单独放置在 doc/source/tutorial/ 下。

有关指导,请参阅现有的 SciPy 子模块。