如何使用for循环而不是while循环遍历Python Queue.Queue?

maj*_*rif 24 python

通常我们这样编码:

while True:
    job = queue.get()
    ...
Run Code Online (Sandbox Code Playgroud)

但它是否也可以做以下事情:

for job in queue.get():
    #do stuff to job
Run Code Online (Sandbox Code Playgroud)

我想要这样做的真正原因是因为我想使用python-progressbar的自动检测maxval.他们这样做for this in progressbar(that):

fal*_*tru 39

你可以使用itercallable.(你应该传递两个参数,一个用于可调用,另一个用于sentinel值)

for job in iter(queue.get, None): # Replace `None` as you need.
    # do stuff with job
Run Code Online (Sandbox Code Playgroud)

注意当没有元素保留且没有放置标记值时,这将阻止.此外,像一个while- get环不像正常for了集装箱的循环,它会从队列中删除的项目.

  • @larsmans,只有当你传递`block = False`时. (2认同)

小智 13

我会说这是在某些方面迭代队列的简单方法:

from queue import Queue

q = Queue()
q.put(1)
q.put(2)
q.put(3)

for i in q.queue:
    print(i)
Run Code Online (Sandbox Code Playgroud)


Alf*_*lfe 8

对于那种队列实际上我通常不会使用这种检查,queue.empty()因为我总是在线程上下文中使用它,因此无法知道另一个线程是否会在几毫秒内放置一些东西(因此检查无论如何都是无用的).我从不检查队列是否为空.我宁愿使用标记生产者结尾的sentinel值.

所以使用iter(queue.get, Sentinel)更多是我喜欢的.

如果您知道没有其他线程将项目放入队列中,并且只想将其从当前包含的所有项目中排除,那么您可以使用这样的:

class Drainer(object):
  def __init__(self, q):
    self.q = q
  def __iter__(self):
    while True:
      try:
        yield self.q.get_nowait()
      except queue.Empty:  # on python 2 use Queue.Empty
        break

for item in Drainer(q):
  print(item)
Run Code Online (Sandbox Code Playgroud)

要么

def drain(q):
  while True:
    try:
      yield q.get_nowait()
    except queue.Empty:  # on python 2 use Queue.Empty
      break

for item in drain(q):
  print(item)
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 7

我的第一个虽然是 iter 函数,但内置的队列模块不返回哨兵,所以一个很好的选择可能是定义你自己的包装类:

import Queue

class IterableQueue():
    def __init__(self,source_queue):
            self.source_queue = source_queue
    def __iter__(self):
        while True:
            try:
               yield self.source_queue.get_nowait()
            except Queue.Empty:
               return
Run Code Online (Sandbox Code Playgroud)

这个迭代器包装队列并产生直到队列为空,然后返回,所以现在你可以这样做:

q = Queue.Queue()
q.put(1)
q.put(2)
q.put(3)

for n in IterableQueue(q):
    print(n)
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
Run Code Online (Sandbox Code Playgroud)

这种方法有点冗长,如果有人使用内置函数更好地了解它会很有趣。