簡體   English   中英

"如何使用 for 循環而不是 while 循環遍歷 Python Queue.Queue?"

[英]How to iterate through a Python Queue.Queue with a for loop instead of a while loop?

通常我們這樣編碼:

while True:
    job = queue.get()
    ...

您可以將iter與 callable 一起使用。 (您應該傳遞兩個參數,一個用於可調用對象,另一個用於標記值)

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 job in iter(queue.get, None):

表現與

while True:
  data = queue.get()
  if data is None:
    break

如果有多個進程在起作用。 我沒有可復制的示例,但是前者比后者早結束了。 我認為這可能與訂購和東西有關,但不知道,真的...

如果進程A通過從文件中讀取行並進行轉換來填充隊列。 而且流程B正在從該隊列中消耗資源,我想到在第一個實現中,流程B在例如6個項目之后結束,即使我知道流程A處理了10個項目,然后將哨兵None放入隊列中。

我想這是更簡單的方法

for elem in list(q.queue):
      print(elem)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM