我知道,当对字典执行assertEqual时,会调用assertDictEqual。同样,序列上的assertEqual将执行assertSequenceEqual
但是,当assertDictEqual比较值时,似乎不使用assertEqual,因此不调用assertSequenceEqual
请考虑以下简单字典:

lst1 = [1, 2]
lst2 = [2, 1]

d1 = {'key': lst1}
d2 = {'key': lst2}

self.assertEqual(lst1, lst2) # True
self.assertEqual(d1, d2) # False ><

如何通过递归地将类语义应用于值来测试字典,如d1d2以便正确比较它们的相等性?
我希望尽可能避免使用外部模块(如建议的那样),除非它们是本机Django扩展。
编辑
本质上,我所追求的是一个内置版本:
def assertDictEqualUnorderedValues(self, d1, d2):
    for k,v1 in d1.iteritems():
        if k not in d2:
            self.fail('Key %s missing in %s'%(k, d2))

        v2 = d2[k]

        if isinstance(v1, Collections.iterable) and not isinstance(v1, basestring):
            self.assertValuesEqual(v1, v2)
        else:
            self.assertEqual(v1, v2)

上述代码的问题在于,错误消息不如内置断言那么好,而且可能存在我忽略的边缘情况(正如我刚在头上写下的那样)。

最佳答案

与其重写断言dictEqual,不如先对dict进行递归排序?

def deep_sort(obj):
    """
    Recursively sort list or dict nested lists
    """

    if isinstance(obj, dict):
        _sorted = {}
        for key in sorted(obj):
            _sorted[key] = deep_sort(obj[key])

    elif isinstance(obj, list):
        new_list = []
        for val in obj:
            new_list.append(deep_sort(val))
        _sorted = sorted(new_list)

    else:
        _sorted = obj

    return _sorted

然后排序,并使用普通断言dicteequal:
    dict1 = deep_sort(dict1)
    dict2 = deep_sort(dict2)

    self.assertDictEqual(dict1, dict2)

这种方法的好处是不关心你的列表有多深。

关于python - 如何通过将assertSequenceEqual应用于值来实现assertDictEqual,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18464095/

10-12 03:30