通常我们这样编码:
while True:
job = queue.get()
...
但是,是否有可能做一些事情:
for job in queue.get():
#do stuff to job
我想这样做的真正原因是因为我想使用 python-progressbar 的自动检测 maxval。他们这样做就像for this in progressbar(that):
iter
与可调用一起使用。(您应该传递两个参数,一个用于可调用对象,另一个用于哨兵值)
for job in iter(queue.get, None): # Replace `None` as you need.
# do stuff with job
注意 当没有元素保留且没有放置哨兵值时,这将阻止。此外,与 while
- get
循环不同,与容器上的正常for
循环不同,它将从队列中删除项目。
None
是通用值,因此下面是一个具有更具体哨兵值的示例:
sentinel = object()
for job in iter(queue.get, sentinel):
# do stuff with job
说这是一种在某些点上迭代队列的简单方法:
from queue import Queue
q = Queue()
q.put(1)
q.put(2)
q.put(3)
for i in q.queue:
print(i)
对于这种队列,实际上我通常不会使用这种queue.empty()
检查,因为我总是在线程上下文中使用它,因此无法知道另一个线程是否会在几毫秒内将某些东西放在那里(因此该检查无论如何都是无用的)。 我从不检查队列是否为空。 我宁愿使用一个哨兵值来标记生产者的结局。
所以使用iter(queue.get, Sentinel)
是我喜欢的。
如果您知道没有其他线程将项目再放入队列中,并且只想从所有当前包含的项目中排出它,那么您可以像这样使用 sth:
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)
或
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)
我的第一个是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
这个迭代器包装队列并生成,直到队列为空,然后返回,所以现在你可以这样做:
q = Queue.Queue()
q.put(1)
q.put(2)
q.put(3)
for n in IterableQueue(q):
print(n)
输出:
1
2
3
这种方法有点冗长,如果有人知道使用内置的东西更好,那会很有趣。
我想这是更简单的方法
for elem in list(q.queue):
print(elem)