Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2断言Sequal不正确的结果_Python_Python Unittest - Fatal编程技术网

Python 2断言Sequal不正确的结果

Python 2断言Sequal不正确的结果,python,python-unittest,Python,Python Unittest,我在Python2下的unittest.TestCase.assertItemsEqual函数中遇到了一个有趣的情况;将我的发现发布在这里供子孙后代参考 以下单元测试在Python2下应该成功时中断: import unittest class Foo(object): def __init__(self, a=1, b=2): self.a = a self.b = b def __repr__(self): return '(

我在Python2下的
unittest.TestCase.assertItemsEqual
函数中遇到了一个有趣的情况;将我的发现发布在这里供子孙后代参考

以下单元测试在Python2下应该成功时中断:

import unittest

class Foo(object):
    def __init__(self, a=1, b=2):
        self.a = a
        self.b = b
    def __repr__(self):
        return '({},{})'.format(self.a, self.b)
    def __eq__(self, other):
        return self.a == other.a and self.b == other.b
    def __lt__(self, other):
        return (self.a, self.b) < (other.a, other.b)

class Test(unittest.TestCase):
    def test_foo_eq(self):
        self.assertEqual(sorted([Foo()]), sorted([Foo()]))
        self.assertItemsEqual([Foo()], [Foo()])

unittest.main()
这相当令人困惑,因为州政府:

它[
assertItemsEqual
]相当于
assertEqual(已排序(预期)、已排序(实际))
,但它也适用于不可损坏对象的序列

在Python3下通过了相同的测试(将
self.assertItemsEqual
替换为
self.assertCountEqual
,因为名称已更改)


编辑:在发布这个问题之后,我确实发现了另一个问题,它涵盖了既没有定义
\uuuuueq\uuuuu
也没有定义
\uuuuuhash\uuuuuu
的情况。

为了让测试在Python2和Python3下都通过,我必须在
Foo
中添加一行
\uuhash\uuuuu=None

assertItemsEqual
/
assertCountEqual
函数根据每个列表中的项目是否可散列而采用不同的代码路径。并根据:

如果类没有定义
\uuuu cmp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;如果它定义了
\uu cmp\uu()
\uu eq\uuu()
而不是
\uuu hash\uuu()
,则其实例将无法在哈希集合中使用

考虑到这一点,定义了
\uuuuuueq\uuuuu
时,Python 2和3在
\uuuuuuuu散列
方面有不同的行为:

  • 在Python2中,定义
    \uuuuuueq\uuuu
    不会影响提供的默认值
    \uuuuuuu散列
    ,但尝试在散列容器中使用该项会导致实现定义的行为(例如,键可能会被复制,因为它们具有不同的散列,即使
    \uuuuuueq\uuu
    将返回
    True
  • 在Python3中,定义
    \uuuuuu eq\uuuu
    \uuuuu hash\uuuu
    设置为
    None
从Python2.6开始,
\uuu hash\uu
可以显式设置为
None
,以使类不可破坏。在我的例子中,这是获得
assertItemsEqual
所必需的,以使用正确的比较算法,该算法依赖于
\uuuuuuuueq\uuuuu
,而不是
\uuuuuuuhash\uuuuu

======================================================================
FAIL: test_foo_eq (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tsanders/scripts/one_offs/test_unittest_assert_items_equal2.py", line 17, in test_foo_eq
    self.assertItemsEqual([Foo()], [Foo()])
AssertionError: Element counts were not equal:
First has 1, Second has 0:  (1,2)
First has 0, Second has 1:  (1,2)

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)