ndarray子类的平等性没有达到预期的效果

时间:2013-07-04 13:10:13

标签: python numpy

以下示例:

import numpy as np

class SimpleArray(np.ndarray):

    __array_priority__ = 10000

    def __new__(cls, input_array, info=None):
        return np.asarray(input_array).view(cls)

    def __eq__(self, other):
        return False

a = SimpleArray(10)
print (np.int64(10) == a)
print (a == np.int64(10))

给出以下输出

$ python2.7 eq.py
True
False

这样在第一种情况下,SimpleArray.__eq__不会被调用(因为它应该总是返回False)。这是一个错误,如果是这样,任何人都可以想到一个解决方法吗?如果这是预期的行为,我如何确保在两者中调用SimpleArray.__eq__

编辑:只是为了澄清,这个只有与Numpy标量数组一起发生 - 正常数组__eq__总是被调用,因为__array_priority__告诉Numpy它应该总是执行即使对象在相等操作的RHS上,这个__eq__

b = SimpleArray([1,2,3])

print(np.array([1,2,3]) == b)
print(b == np.array([1,2,3]))

给出:

False
False

所以看来,对于标量Numpy'数组',__array_priority__没有得到尊重。

3 个答案:

答案 0 :(得分:1)

这介于bug和wart之间。当您调用a op b并且ba python检查的子类时,查看b是否具有op的反映版本并调用({{1}它是自身的反射版本),例如,这个__eq__给出了预期的结果,因为SimpleArray是ndarray的子​​类。但是,因为SimpleArray不是np.int64的实例,所以它在您提供的示例中不起作用。这实际上可能很容易修复到numpy端,所以你可以考虑把它放在邮件列表上。

答案 1 :(得分:0)

默认情况下,等式a == b调用A.__eq__(),其中A是变量a的类。这意味着左操作数的类型决定了调用哪个相等函数。确保您编写的相等函数的唯一方法是确保您的变量始终是左操作数。但是,如果左操作数没有相等的函数,python尝试调用B.__eq__()

答案 2 :(得分:0)

如果other属于不同类型,则__eq__等运算符方法需要第二个反射函数,该函数知道如何处理相反方向的比较。由于__eq__没有反向,而是使用__cmp__及其反向__rcmp__

另见http://docs.python.org/2/reference/datamodel.html#basic-customization