【问题标题】:assertEqual fails for objects that are byte-for-byte identical?对于逐字节相同的对象,assertEqual 失败?
【发布时间】:2018-04-30 16:18:11
【问题描述】:

我有一个单元测试,可以比较两个像这样的单元素字典:

{SomeClass(): SomeOtherClass()}

dicts 看起来和肉眼完全一样,key 和 value 的类型也是一样的。尽管如此,测试还是失败了。

我当然尝试了各种技巧来在它们之间产生一些差异输出,但没有一个显示出这些对象或任何嵌套属性之间的任何差异。对象很大,所以 unittest diff 没有帮助。

作为最后一次绝望的尝试,我尝试腌制这些字典,然后制作 Unix 差异,但这也没有任何区别。称我为天真,但对我来说,这意味着这些对象是逐字节相同的,并且测试应该通过。这是怎么回事?

【问题讨论】:

  • 类型从何而来?如果他们有 __eq__ 等的自定义实现,他们可以假装(即使有充分的理由)不等于任何东西。
  • SomeClass 是一个没有自定义相等定义的 attrs 类,SomeOtherClass 一个没有 __hash__/__eq__ 的普通 Python 类。
  • 好的,事实证明你绝对必须在第二类中实现 __eq__ 。 Python 有时真的很烦人:(
  • 相同的泡菜并不意味着逐字节相同的对象,逐字节相同的对象也不一定相等。
  • 感谢您为我指明了正确的方向。我觉得您的两个命题中的后一个应该绝对正确,无需任何额外的样板代码。

标签: python assert python-unittest


【解决方案1】:

相同的泡菜并不意味着逐字节相同的对象,并且逐字节相同的对象不一定相等。

您可能认为使逐字节相同的对象自动相等很容易,但这会遇到很多问题。例如,考虑以下情况:

class Foo(object):
    __slots__ = ['x']

x = Foo()
y = Foo()
x.x = y.x = x

除了 GC 元数据之外,xy 可能逐字节相同。 xy 是否应该自动相等? x 是唯一一个其x 属性指向自身的;这似乎是一个足够大的差异,它们不应该自动相等。

这只是默认情况下尝试做你想做的事情的问题之一。事实证明,最不容易混淆的默认设置是让== 按身份工作;除非 __eq__ 覆盖发挥作用,否则对象将只等于它们自己。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多