我使用 Python 的unittest
模块,想检查两个复杂的数据结构是否相等。对象可以是具有各种值的字典列表:数字、字符串、Python 容器(列表/元组/字典)和numpy
数组。后者是问这个问题的原因,因为我不能只是做
self.assertEqual(big_struct1, big_struct2)
因为它产生一个
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
我想我需要为此编写自己的平等测试。它应该适用于任意结构。我目前的想法是一个递归函数:
- 尝试将当前“节点”
arg1
与 的相应节点进行直接比较arg2
; - 如果没有引发异常,则继续(“终端”节点/叶子也在此处处理);
- 如果
ValueError
被捕获,则继续深入,直到找到一个numpy.array
; - 比较数组(例如像这样)。
跟踪两个结构的“对应”节点似乎有点问题,但也许zip
我在这里只需要。
问题是:这种方法是否有更好(更简单)的替代方案?也许numpy
为此提供一些工具?如果没有建议替代方案,我将实施这个想法(除非我有更好的想法)并作为答案发布。
PS我有一种模糊的感觉,我可能已经看到了一个解决这个问题的问题,但我现在找不到它。
PPS 另一种方法是遍历结构并将所有numpy.array
s 转换为列表的函数,但这更容易实现吗?对我来说似乎一样。
编辑:子类numpy.ndarray
化听起来很有希望,但显然我没有将比较的双方硬编码到测试中。但是,其中一个确实是硬编码的,所以我可以:
numpy.array
用;的自定义子类填充它- 更改
isinstance(other, SaneEqualityArray)
为jterraceisinstance(other, np.ndarray)
的答案; - 在比较中始终将其用作 LHS。
我在这方面的问题是:
- 它会起作用吗(我的意思是,这对我来说听起来不错,但可能无法正确处理一些棘手的边缘情况)?如我所料,我的自定义对象在递归相等检查中总是以 LHS 结尾吗?
- 同样,有没有更好的方法(假设我得到了至少一个带有真实
numpy
数组的结构)。
编辑2:我试过了,这个答案中显示了(看似)工作的实现。