
numpy.divide 是一个 ufunc(通用函数)实例,它既支持直接调用(如 np.divide(a, b)),又拥有绑定方法(如 .outer)和属性,这是因其底层实现了 __call__ 协议并封装了丰富的运算能力。
`numpy.divide` 是一个 `ufunc`(通用函数)实例,它既支持直接调用(如 `np.divide(a, b)`),又拥有绑定方法(如 `.outer`)和属性,这是因其底层实现了 `__call__` 协议并封装了丰富的运算能力。
在 NumPy 中,np.divide 并非普通函数(<class></class>),也不是用户定义的类(<class></class>),而是一个 numpy.ufunc 类的实例 —— 即一个“可调用对象”(callable object)。这种设计融合了面向对象与函数式编程的优势:
- ✅ 它可被直接调用:
np.divide(a, b)等价于np.divide.__call__(a, b); - ✅ 它自带预定义的广播方法:如
.outer、.reduce、.accumulate、.at等; - ✅ 它是 NumPy 向量化计算的核心抽象,所有基础运算(
add、multiply、sin等)均以ufunc实例形式暴露。
例如,以下代码清晰展示了其双重特性:
import numpy as np
a, b = np.array([1, 2, 3]), np.array([2, 3])
# 1. 直接调用:执行逐元素除法(广播后)
result = np.divide(a, b) # shape: (3,) / (2,) → (3, 2) via broadcasting? 不,实际是按规则对齐 → 报错!需注意维度
# 更稳妥示例:
c = np.divide(np.array([6, 8, 10]), np.array([2, 4])) # OK: (3,) vs (2,) → 触发广播,结果为 (3, 2)
# 2. 调用内置方法:outer 实现外积(笛卡尔除法)
d = np.divide.outer(np.array([2, 4]), np.array([1, 2, 4])) # shape: (2, 3)
# 输出:[[2. 1. 0.5], [4. 2. 1.]]
print(f"{d=}")
关键在于:ufunc 类重载了 __call__ 方法,使其实例表现得像函数;同时作为对象,它自然可以拥有属性和方法(如 np.divide.outer 实际是 ufunc.outer 的绑定方法)。这与 sys.stderr.write 的区别正在于此:
-
sys.stderr是文件对象(不可调用),write是其普通方法; -
np.divide是ufunc实例(可调用),outer是其预绑定的 ufunc 特有方法,专为向量化组合运算设计。
⚠️ 注意事项:
ufunc方法(如.outer)并非所有函数都有——仅限 NumPy 内置 ufunc(如add,multiply,logical_or),自定义函数无法直接获得.outer;np.divide.outer(a, b)等价于np.divide(a[:, None], b[None, :]),但更高效、语义更清晰;- 查看可用方法:
dir(np.divide)可列出outer,reduce,accumulate等;help(np.divide.outer)提供详细文档。
简言之:np.divide 是一个高度工程化的可调用对象,它不是“既是类又是函数”的模糊体,而是 Python 面向对象机制(__call__ + 属性/方法)在科学计算中的典范应用——兼具简洁接口与强大表达力。











