如何强制调用反射特殊方法__r...__?以numpy与自定义对象相加为例
如何让numpy数组与自定义对象相加时调用自定义对象的__radd__方法
我需要实现some_numpy_array + CustomObject时,强制调用CustomObject.__radd__而不是numpy数组的__add__——后者在我的场景下无法正常工作。
问题示例代码
import numpy as np class CustomObject: # 简称co def __init__(self, arr): self.arr = arr def __add__(self, other): if isinstance(other, CustomObject): return self.arr + other.arr return self.arr + other def __radd__(self, other): return self.__add__(other) npa = np.array([1, 10.]) coa = CustomObject(npa) print(npa + npa) # [ 2. 20.] # 调用np.__add__ print(coa + coa) # [ 2. 20.] # 调用co.__add__ print(coa + npa) # [ 2. 20.] # 调用co.__add__ print(npa + coa) # [array([ 2., 11.]) array([11., 20.])] # 调用np.__add__,但我希望调用co.__radd__
解决方案:实现__array_ufunc__钩子方法
numpy的数组类型在运算时会优先使用自身的__add__,不会主动触发右侧自定义对象的__radd__。要改变这个行为,我们可以给CustomObject添加__array_ufunc__方法——这是numpy为自定义对象提供的通用函数运算接口,能让我们接管自定义对象与numpy数组之间的运算逻辑。
修改后的类代码:
import numpy as np class CustomObject: def __init__(self, arr): self.arr = arr def __add__(self, other): if isinstance(other, CustomObject): return self.arr + other.arr return self.arr + other def __radd__(self, other): return self.__add__(other) def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): # 仅处理加法操作的调用场景 if ufunc is np.add and method == '__call__': # 遍历输入,找到numpy数组并调用__radd__处理 for inp in inputs: if isinstance(inp, np.ndarray): return self.__radd__(inp) # 其他运算场景交给默认逻辑处理 return NotImplemented
测试验证
运行以下代码:
npa = np.array([1, 10.]) coa = CustomObject(npa) print(npa + coa) # 输出 [ 2. 20.],成功调用co.__radd__
原理说明
__array_ufunc__会在numpy数组与自定义对象进行通用函数(如np.add)运算时被触发。我们在这个方法中判断当前是加法操作后,主动调用自定义对象的__radd__来处理运算,从而绕过numpy数组默认的加法逻辑,达到我们想要的效果。
内容的提问来源于stack exchange,提问作者Louis-Amand
相关产品推荐
相关产品推荐

