我对格式为 <ndarray> + <my object> 的 __radd__ 有疑问

I hace issue with __radd__ with format < ndarray> + <my object>

我是 Python 的初学者。

我试图理解 addradd 的行为 通过我的 class 点的简短测试代码。

我想以不同的形式使用加法 < + >,例如:

  1. 点 + 整数
  2. 点+浮点数
  3. Point + str 如果可以转换成int或float
  4. 点 + ndarray

在我的 class 代码中使用 def_add_( ) 方法,这很好,我对每种情况都没有问题

但是!!!使用代码中的 def_radd_( ) 方法,我只得到一个奇怪的问题 ndarray + 点

我的代码

import numpy as np
class Point():
    def __init__(self, x = 0.0, y = 0.0, z = 0.0):
        self.point = np.array([x*1.0, y*1.0, z*1.0])

    def valeur(self):
        return self.point

    def __str__(self):
        return f"point : {self.point}"

    def __add__(self, other):
        #it's OK
        pass

    def __radd__(self, other):
        print( "__radd__  >>> self = ", self, "  other = ", other,end = '')
        if isinstance(other, np.ndarray ):
            print("<array>   + <Point> ", end = '' )
            a = self.point + other*1.0
            return Point(a[0], a[1], a[2]) 

        elif isinstance(other, int):
            print("   therefore we are in case <int> + <Point> we use __radd__  ", end = '' )
            a = self.point + other*1.0
            print(a)
            return Point(a[0], a[1], a[2])

        # elif other cases for str and float . The booth run whele

        else:
            return self.point

if __name__ == "__main__":
    point1 = Point( -1, 2, 1)
    print(point1)
    print("\nwhith the format np.array( [10, 20, 30 ] ) + point1.valeur() it's OK but it's not my target")
    print(np.array( [10, 20, 30 ] ) + point1.valeur())
    print("\nwhith the format ndarray + Point it's NOK. I obtain 3 calls of __radd__ for each elements of ndarray")
    print( "\n result IT'S NOT OK  ==> \n", np.array( [10, 20, 30 ] ) + point1 )

输出为:

 point : [-1.  2.  1.]

 whith the format np.array( [10, 20, 30 ] ) + point1.valeur() it's OK but it's not my target
 [ 9. 22. 31.]

 whith the format ndarray + Point it's NOK. I obtain 3 calls of __radd__ for each elements of ndarray

 __radd__  >>> self =  point : [-1.  2.  1.]   other =  10   therefore we are in case <int> + <Point> we use __radd__  [ 9. 12. 11.]

 __radd__  >>> self =  point : [-1.  2.  1.]   other =  20   therefore we are in case <int> + <Point> we use __radd__  [19. 22. 21.]

 __radd__  >>> self =  point : [-1.  2.  1.]   other =  30   therefore we are in case <int> + <Point> we use __radd__  [29. 32. 31.]

 result IT'S NOT OK  ==>  
 [<__main__.Point object at 0x00000214E00BBA30>
  <__main__.Point object at 0x00000214E00E5EB0>
  <__main__.Point object at 0x00000214EEDC3C40>]

3个地址列表分别与[9.12.11.]、[19. 22. 21.] 和 [29. 32. 31.]

我很惊讶:我认为使用的测试会是真的:if isinstance(other, np.ndarray ):

我的问题是:为什么左边的 ndarray 给每个元素而不是一个完整的 ndarray

NumPy 的

ndarray 有点特殊 class 实现 ndarray + object for any 对象,它有比 ndarray + PointPoint.__radd__。要改变这种行为,您需要

    # Add this method to class Point.
    def __array_ufunc__(self, ufunc, method, *args, **kwargs):
        if len(args) == 2 and len(kwargs) == 0:
            x = args[0]
            y = args[1]
            if isinstance(x, np.ndarray) and isinstance(y, Point):
                if ufunc is np.add:
                    return y.__radd__(x)
        return NotImplemented

参见 https://numpy.org/doc/stable/reference/arrays.classes.html