NumPy源码__init__.py中先导入模块再`import *`的设计意图是什么?
NumPy源码中重复导入模式的设计原因
我在NumPy源码的__init__.py模块中反复看到如下模式:先执行from . import numeric将模块内容导入numeric命名空间,再执行from .numeric import *将其导入当前命名空间。我困惑于这种将同一内容导入两个不同命名空间的设计原因,也不确定是否理解有误。已验证该模式下的函数可在两个命名空间中访问,示例代码如下:
import numpy # 基于numpy v.1.26.x测试 ## 函数`zeros()`可在`core`命名空间访问 numpy.core.zeros((3, 2)) # 输出:3×2的二维零数组 ## 函数`zeros()`可在当前命名空间访问 numpy.zeros((3, 2)) # 输出:3×2的二维零数组
这种设计主要有几个实际作用:
- 兼容新旧代码:早期NumPy的API中,很多函数是放在子模块(比如
numpy.core.numeric)里的,后来为了简化使用,把常用函数提升到顶层命名空间。保留子模块的导入,能保证依赖旧路径的代码依然能正常运行。 - 模块结构清晰:通过保留
numeric子模块的命名空间,开发者可以明确知道函数的原始归属,方便阅读和维护源码,同时顶层的*导入又让用户不用记住复杂的子模块路径,直接用numpy.zeros这种简洁写法。 - 内部引用便利:在NumPy的其他内部模块中,有时候需要明确引用子模块里的内容(避免和其他模块的同名函数冲突),这时候
from . import numeric导入的命名空间就能派上用场,而顶层导入则是给外部用户提供便利。
另外需要说明,from .numeric import *并不是导入子模块的所有内容,NumPy的子模块通常会定义__all__变量,只导出约定好的公共API,这样顶层命名空间不会被无关的内部实现内容污染。
内容的提问来源于stack exchange,提问作者qwerty
相关产品推荐
相关产品推荐

