You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制调用反射特殊方法__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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:22:44