简体   繁体   中英

python loop a queue without while

I'm now playing with multiprocessing and queue in Python 2.7 and try to print out 0 to 7 with variable p. When while is used as the commented codes shown in option 1, it works. However when the for and iter() are used as shown in option 2, 0 to 7 do print, yet the program never exits the loop and I have to exit manually. Any suggestions on how to modify the codes to have the loop exit normally after printing? With iter() , is there a way to set the block=False for the input arg p.get ?

def try_queue():
    q = Queue()
    for i in range(10):
        q.put(i)

    p = Queue()
    for j in iter(q.get,8):
        p.put(j)

    # option 1, use while, works. 
    # while not p.empty():
    #   print(p.get()) 

    # option 2, use iter()
    for k in iter(p.get, None): # None is the sentinel here
        print(k)

try_queue()

Result of option 1

Result of option 2

You cannot easily achieve that because the Queue does not support the iterator protocol . Reason for this is the Queue is designed to be a message passing object rather than a container.

The Queue.get method does not ensure the Queue is actually empty . Therefore, keep this in mind when you are writing your logic: that's not the way a Queue is intended to be used. Think it more as a sort of "socket" between threads/processes.

Here are two ways to achieve what you want.

1) Create a IterQueue class which supports the iterator protocol.

from Queue import Queue

class IterQueue(Queue):
    """Queue supporting iterator protocol."""
    def __iter__(self):
        return self

    def next(self):
        if self.empty():
            raise StopIteration()

        return self.get()

queue = IterQueue()
for element in queue:
    print element

2) Wrap the get call into a generator. This technically hides the while loop from your logic.

def get_next_element(queue):
    while not queue.empty():
        yield queue.get()

for element in get_next_element(queue):
    print element

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM