由于Python不提供其比较运算符的左/右版本,它如何决定调用哪个函数?
class A(object):
def __eq__(self, other):
print "A __eq__ called"
return self.value == other
class B(object):
def __eq__(self, other):
print "B __eq__ called"
return self.value == other
>>> a = A()
>>> a.value = 3
>>> b = B()
>>> b.value = 4
>>> a == b
"A __eq__ called"
"B __eq__ called"
False
Run Code Online (Sandbox Code Playgroud)
这似乎称为两种__eq__功能.只是寻找官方的决策树.
我使用Python的unittest模块,并想检查两个复杂的数据结构是否相等.对象可以是具有各种值的dicts列表:数字,字符串,Python容器(列表/元组/ dicts)和numpy数组.后者是提出问题的原因,因为我不能这样做
self.assertEqual(big_struct1, big_struct2)
Run Code Online (Sandbox Code Playgroud)
因为它会产生一个
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)
我想我需要为此编写自己的相等测试.它应该适用于任意结构.我目前的想法是递归函数:
arg1到相应节点arg2;ValueError被抓住,会更深入,直到找到numpy.array;看起来有点问题的是跟踪两个结构的"相应"节点,但也许这zip就是我所需要的.
问题是:这种方法有更好(更简单)的替代方案吗?也许numpy为此提供了一些工具?如果没有建议的替代方案,我将实施这个想法(除非我有一个更好的想法)并发布作为答案.
PS我有一种模糊的感觉,我可能已经看到了解决这个问题的问题,但我现在找不到它.
PPS另一种方法是遍历结构并将所有numpy.arrays 转换为列表的函数,但是这更容易实现吗?对我来说似乎一样.
编辑:子类化numpy.ndarray听起来很有希望,但显然我没有将比较的两面硬编码到测试中.但其中一个确实是硬编码的,所以我可以:
numpy.array;isinstance(other, SaneEqualityArray)以isinstance(other, np.ndarray)在jterrace的答案 ;我在这方面的问题是:
numpy数组的结构).编辑2:我试了一下,(看似)工作实现在这个答案中显示 …
我以前从未处理过反向操作员,所以请不要燃烧!刚刚完成了解它们,所以想尝试一下.但由于某种原因,它不起作用.这是代码:
>>> class Subtract(object):
def __init__(self, number):
self.number = number
def __rsub__(self, other):
return self.number - other.number
>>> x = Subtract(5)
>>> y = Subtract(10)
>>> x - y # FAILS!
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
x - y
TypeError: unsupported operand type(s) for -: 'Subtract' and 'Subtract'
>>> x.__rsub__(y) # WORKS!
-5
Run Code Online (Sandbox Code Playgroud)
如果我改变__rsub__到__sub__,它的工作原理.
我究竟做错了什么?这些反向运营商的目的是什么?