【问题标题】:Why do I run into an infinite loop without __contains__?为什么我在没有 __contains__ 的情况下会陷入无限循环?
【发布时间】:2020-04-18 10:02:53
【问题描述】:

下面的代码会陷入死循环:

class SubCommandMap:

    def __init__(self):
        self._command = dict()

    def __getitem__(self, key):
        return self._command.get(key)

    def __setitem__(self, key, value):
        self._command[key] = value

m = SubCommandMap()
" " in m   # <- why is this an infinite loop?

当然这是一个错误。 m 被认为是不同类型的不同对象。 但是为什么这会导致无限循环而不是抛出异常呢?

我添加了以下方法:

    def __contains__(self, other):
        raise NotImplementedError()

现在我收到了相应的错误消息。

还有其他类似的情况我需要小心避免无限循环吗?

【问题讨论】:

    标签: python infinite-loop


    【解决方案1】:

    在没有__contains__ 的情况下,in 运算符将使用您定义的__getitem__ 方法来查看它是否获得了您正在寻找的对象。它将依次将每个 int 传递给__getitem__,直到找到该项目或该方法引发异常。如果这两种情况都没有发生,那么你就有了一个无限循环。

    【讨论】:

    • 确实,一种解决方法是将__getitem__ 更改为使用普通索引而不是调用dict.get,这样虚假索引就会引发IndexError 而不是返回None
    • ...因为__getitem__ 中的dict.get(...) 将始终返回None - 从来没有真实的价值
    【解决方案2】:

    是的,还有其他类似的案例。

    • 如果__getitem__ 不引发异常,则尝试迭代实现__getitem__ 但未实现__iter__ 的对象是一个无限循环。见this question

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 2016-04-08
      • 2010-11-01
      • 2020-07-13
      • 2019-12-23
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多