Numpy调用时是否检查数据类型与长度?检查的源码位置在哪?
Numpy调用时的数据类型与长度检查问题
问题
请问调用Numpy时,它是否会对数据类型与长度进行检查?负责该检查逻辑的源码位于何处?
复现代码
import numpy as np class P(list): def __init__(self, achievement=[]): self.achievement = achievement self.extend(achievement) def __len__(self): print('___len___') print(self.achievement) return 2.0 def __getitem__(self, idx): return 1/0 j = P([1,2,3]) np.log(j)
触发的错误
TypeError: loop of ufunc does not support argument 0 of type P which has no callable log method
解答
- Numpy的检查行为
Numpy在调用np.log这类通用函数(ufunc)时,确实会执行数据类型兼容性检查,但对自定义类的长度检查逻辑依赖于对象是否实现了Numpy可识别的数组接口:
- 当处理非Numpy数组的对象时,Numpy首先会检查对象是否实现了
__array__方法(标准数组接口),如果没有,会 fallback 到迭代处理逻辑。 - 迭代过程中会调用对象的
__len__获取长度,但你代码中__len__返回浮点数的问题并不是触发报错的直接原因——真正的错误是:Numpy无法找到自定义类P对应的log方法,也无法将其转换为可处理的数值数组,因此抛出类型错误。
- 检查逻辑的源码位置
Numpy中处理ufunc参数类型检查的核心逻辑集中在以下几个核心源码文件(基于Numpy主分支):
numpy/core/src/ufunc/methods.c:包含ufunc对不同类型参数的分发逻辑,负责检查参数是否支持对应的ufunc操作。numpy/core/src/multiarray/array_method.c:处理对象的数组接口适配,包括验证对象是否可转换为Numpy数组。numpy/core/src/ufunc/ufunc_object.c:ufunc对象的核心实现,是参数类型验证、调度的入口。
补充建议
如果想让自定义类被Numpy正确处理,推荐实现__array__方法返回对应的Numpy数组,或者实现__array_ufunc__方法直接处理Numpy的ufunc调用,这样可以自定义类型适配逻辑,绕过默认的检查流程。
内容的提问来源于stack exchange,提问作者fafa
相关产品推荐
相关产品推荐

