Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 可重分配队列_Python_Queue_Iteration - Fatal编程技术网

Python 可重分配队列

Python 可重分配队列,python,queue,iteration,Python,Queue,Iteration,我需要知道队列何时关闭,不会有更多的项目,这样我才能结束迭代 我在队列中设置了一个哨兵: from Queue import Queue class IterableQueue(Queue): _sentinel = object() def __iter__(self): return self def close(self): self.put(self._sentinel) def next(self):

我需要知道队列何时关闭,不会有更多的项目,这样我才能结束迭代

我在队列中设置了一个哨兵:

from Queue import Queue

class IterableQueue(Queue): 

    _sentinel = object()

    def __iter__(self):
        return self

    def close(self):
        self.put(self._sentinel)

    def next(self):
        item = self.get()
        if item is self._sentinel:
            raise StopIteration
        else:
            return item

鉴于这是队列的一个非常常见的用途,是否有任何内置实现?

多处理模块有自己的版本,其中包括一个
close
方法。我不确定它在线程中是如何工作的,但值得一试。我不明白为什么它不能起同样的作用:

来自多处理导入队列的

q=队列()
q、 付诸表决(1)
q、 获取_nowait()
# 1
q、 关闭()
q、 获取_nowait()
# ...
#IOError:select()中的句柄超出范围
你可以捕捉到IOError作为关闭信号

测试

from multiprocessing import Queue
from threading import Thread

def worker(q):
    while True:
        try:
            item = q.get(timeout=.5)
        except IOError:
            print "Queue closed. Exiting thread."
            return
        except:
            continue
        print "Got item:", item

q = Queue()
for i in xrange(3):
    q.put(i)
t = Thread(target=worker, args=(q,))
t.start()
# Got item: 0
# Got item: 1
# Got item: 2
q.close()
# Queue closed. Exiting thread.
老实说,这与在Queue.Queue上设置标志没有太大区别。multiprocessing.Queue只是使用一个关闭的文件描述符作为标志:

from Queue import Queue

def worker2(q):
    while True:
        if q.closed:
            print "Queue closed. Exiting thread."
            return
        try:
            item = q.get(timeout=.5)
        except:
            continue
        print "Got item:", item

q = Queue()
q.closed = False
for i in xrange(3):
    q.put(i)
t = Thread(target=worker2, args=(q,))
t.start()
# Got item: 0
# Got item: 1
# Got item: 2
q.closed = True
# Queue closed. Exiting thread.

哨兵是生产者发送不再有队列任务即将到来的消息的合理方式

FWIW,您的代码可以通过以下两种参数形式简化:


我或者使用sentinel,或者线程中的标志来停止队列上的迭代。对于后者,我通常会超时等待。
from Queue import Queue

class IterableQueue(Queue): 

    _sentinel = object()

    def __iter__(self):
        return iter(self.get, self._sentinel)

    def close(self):
        self.put(self._sentinel)