【问题标题】:How does this loop works: for item in iter(queue.get, None)?这个循环是如何工作的:for item in iter(queue.get, None)?
【发布时间】:2015-04-20 21:36:52
【问题描述】:

我正在使用 python Queue 来存储要由线程处理的项目。根据我在网上阅读的内容,将“无”对象放入队列并像这样设置线程处理将使线程停止。 (确实如此)

for item in iter(queue.get, None):
    #do stuff
    queue.task_done()

现在我在网上找不到很多关于这种 for 循环的信息。据我所见,它刚刚结束,不会处理任何其他将 None 对象留在队列中的内容。 最后添加 queue.task_done() 不起作用。

谁能向我解释一下这种类型的 for 循环。它们是如何命名的,它们一般是如何工作的,或者因为我找不到任何关于它的好文档,所以请我指点我。

【问题讨论】:

  • 此循环中的密钥是iter() 的替代签名 - 不是使用可迭代调用它,而是用作iter(callable, sentinel),它将调用callable() 并产生结果,直到它等于sentinel,表示迭代结束。请参阅this answer 以获得更易于理解的示例。
  • 注意,需要在for循环后添加queue.task_done()调用,标记哨兵任务完成,否则queue.join()会挂掉。

标签: python multithreading


【解决方案1】:

这一行:

for item in iter(queue.get, None):

读取

"继续调用queue.get,然后运行循环体,直到queue.get() == None

【讨论】:

    【解决方案2】:

    the documentation for the iter() function:

    如果给定第二个参数 sentinel,则 o 必须是可调用对象。在这种情况下创建的迭代器将调用 o,每次调用其next() 方法时不带任何参数;如果返回的值等于sentinelStopIteration 将被提升,否则该值将被返回。

    所以循环的行为相当于:

    sentinel = None
    while True:
      item = queue.get()
      if item == sentinel:
        break
      # do stuff
      queue.task_done()
    

    【讨论】:

    • is sentinel== sentinel?
    • @Eric:很好。是的,语义是== sentinel 的语义。已更新。
    【解决方案3】:

    这是iter()的第二种形式:

    iter(callable, sentinel) -> iterator
    

    在第二种形式中,调用 callable 直到它返回哨兵。

    (来自help(iter))。

    所以每次for-statement尝试从iter返回的迭代器中获取一个元素时,它调用queue.get(),检查是否返回不是None,并将返回值作为item传递给for-statement-body。当有人将 None-terminator 推入队列时,queue.get() 返回 None 导致迭代器抛出 StopIteration 并且解释器离开 for-statement 块。

    【讨论】:

      【解决方案4】:

      我认为最重要的部分是:

      注意当没有元素剩余并且没有放置哨兵值时,这将阻塞。

      所以基本上这个方法不会自动在任何队列上运行,你必须放一个None值来表示进程结束

      【讨论】:

        【解决方案5】:

        我注意到这些方法在特定的多处理环境中有所不同。描述here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-25
          • 1970-01-01
          • 2014-05-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多