【问题标题】:How to force dicts to be unordered (for testing)?如何强制 dicts 无序(用于测试)?
【发布时间】:2017-08-08 15:56:30
【问题描述】:

我刚刚花了半天时间将一个错误追踪到一个我在迭代它时忘记排序的字典。即使这部分代码已经过测试,测试也没有选择它,因为该 dict 在测试期间具有可重复的顺序。 只有当我洗牌时,测试才会失败!(我使用了一个中间 random.shuffle'd 列表并构建了一个 OrderedDict)

这让我有点害怕,因为可能到处都有类似的错误!

有没有办法在测试期间全局强制所有dicts无序?

更新:我想我至少弄清楚了导致该错误的原因。正如here 所描述的,具有 int 键的字典通常是排序的,但可能并不总是如此。我的假设:在我的测试中,整数总是很小(10 阶),因此总是有序的。然而,在实际运行中,整数要大得多(顺序为 10^13),因此并不总是有序的。我能够在交互式会话中重现此行为:list(foo.keys()) == sorted(foo.keys()) 对于小键始终是 True,但不是对于每个具有非常大键的字典。

【问题讨论】:

  • 字典是 not 排序的。但是在构建时,通常顺序是 deterministic (这是不同的)。您可以将 Python 与 -R 标志一起使用。
  • 使用 -R 标志,给定 Python 进程的键顺序将保持不变,对吧?
  • @RagingRoosevelt:是的。但是每次测试,你都会使用不同的顺序。所以这意味着经过几次测试后,错误可能会开始发生。例如,任意测试是 Haskell 对QuickCheck 使用的东西之一:您生成随机列表/整数/字符串/...并验证条件是否成立。
  • @wim:我不认为这是一个真正的答案。
  • 确实,它只与 Python2 相关,并且问题现在被标记为 Python3。那么,也许您可​​以删除 cmets。

标签: python python-3.x unit-testing


【解决方案1】:

从 3.6 开始,dicts maintain key insertion order。如果您希望它们以特定方式运行,您可以创建一个继承自 dict 的类并为其提供您想要的行为(例如,确保它在返回键列表之前对其进行洗牌)。

无论您使用的 python 版本如何,如果您想尝试依赖 dict 实现的特定行为,请务必查看实现细节。更好的是,为了可移植性,只需编写一个解决方案,以确保它们的行为符合您的预期,就像我上面提到的那样,或者通过在键列表上使用 shuffle 或其他方式。

【讨论】:

  • 哇,不知道。感谢您的告知。
  • 啊,对,我在某个时候读过它,但从那以后我就忘记了。谢谢提醒。
  • 根据链接中的注释:“这个新实现的顺序保留方面被视为实现细节,不应依赖”
  • @Alexander,已编辑以使我的回答更清楚,谢谢!
  • 即使是洗牌也可以随机排列。洗牌是不够的。
猜你喜欢
  • 2020-04-25
  • 1970-01-01
  • 2018-04-30
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
相关资源
最近更新 更多