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 标准库中一个模块的名称。
在某些情况下,公共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.stats.distributions
SciPy 结构#
所有 SciPy 模块应遵循以下约定。在下文中,SciPy 模块 定义为位于 scipy/ 目录中的 Python 包,例如 yyy
。
理想情况下,每个 SciPy 模块应尽可能自包含。也就是说,它应该对其他包或模块的依赖性最小。即使是对于其他 SciPy 模块的依赖也应保持在最低限度。当然,对 NumPy 的依赖是预设的。
目录
yyy/
包含:一个包含子模块构建配置的文件
meson.build
。一个包含文件
test_<name>.py
的目录tests/
,这些文件对应于模块yyy/<name>{.py,.so,/}
。
私有模块应以一个下划线
_
作为前缀,例如yyy/_somemodule.py
。用户可见的函数应有良好的文档,遵循 NumPy 文档风格。
模块的
__init__.py
应该在其文档字符串中包含主要的参考文档。这通过 Sphinx 的 automodule 指令连接到doc/
下的 Sphinx 文档。参考文档应首先使用
autosummary::
指令提供模块内容的分类列表,然后解释理解模块使用的关键点。带有大量示例的教程式文档应单独放置,并放在
doc/source/tutorial/
下。
请参阅现有的 SciPy 子模块以获取指导。