4

我在一个代码库(2.6、2.7 和 3.3+)中仅将 python 库从 python 2 移植到 python 2 和 3。剩下的主要问题是很多测试都使用这样的东西:

def test(self):
 example = {u'foo': u'bar'}
 self.assertEqual(str(example), "{u'foo': u'bar'}")

它适用于 python 2,但在 python3 中引发异常:

 AssertionError: "{'foo': 'bar'}" != "{u'foo': u'bar'}"

除了“测试不同”之外,还有处理这些问题的标准方法吗?超载__repr__

4

2 回答 2

8

摆脱那些测试;它们几乎没用:

  • 这将测试 Python 实现dict.__repr__是否正常工作。Python 本身已经对此进行了测试;而是专注于项目代码库。如果 Python 无法正确呈现字典表示,则修复该问题不是您项目的工作。

  • Python 字典没有固定的顺序;测试它们的表示是否与给定的字符串匹配是不稳定的。

    此外,Python 3.3 引入了哈希随机化,这意味着给定字典的顺序将在调用之间发生变化。见PYTHONHASHSEED

如果您正在测试项目 API 调用的结果,请使用self.assertEqual()代替测试字典是否相等;assertDictEqual()如果两个字典不匹配,它将用于为您提供有意义的错误消息。

由于 Python 3.3 解释u'foo'为 type 的文字str,因此比较输出与{u'foo': u'bar}将在 Python 2.6、2.7 和 3.3 及更高版本中工作。

于 2013-10-23T23:45:40.900 回答
3

我怀疑这不是您的真实代码,并且您的真实代码正在做一些不那么愚蠢的事情:尝试验证字典是否与某些预期结果匹配。

这样做的方法是直接比较字典,而不是比较它们的字符串表示:

self.assertEqual(example, {u'foo': u'bar'})

这适用于 2.x 和 3.x(因为您需要 3.3+,这意味着u前缀是合法的,如果不需要的话)。

于 2013-10-23T23:51:21.367 回答