web-dev-qa-db-fra.com

Comment itérer des éléments Queue.Queue en Python?

Quelqu'un connaît-il une manière Pythonique d'itérer sur les éléments d'un Queue.Queuesans les supprimer de la file d'attente. J'ai un programme de type producteur/consommateur où les articles à traiter sont passés en utilisant un Queue.Queue, et je souhaite pouvoir imprimer les éléments restants. Des idées?

32
pgilmon

Vous pouvez parcourir une copie du magasin de données sous-jacent:

for elem in list(q.queue)

Même si cela contourne les verrous des objets de file d'attente, la copie de la liste est une opération atomique et devrait fonctionner correctement.

Si vous souhaitez conserver les verrous, pourquoi ne pas retirer toutes les tâches de la file d'attente, faire une copie de votre liste, puis les remettre.

mycopy = []
while True:
     try:
         elem = q.get(block=False)
     except Empty:
         break
     else:
         mycopy.append(elem)
for elem in mycopy:
    q.put(elem)
for elem in mycopy:
    # do something with the elements
40
Raymond Hettinger

Liste des éléments de file d'attente sans les consommer:

>>> from Queue import Queue
>>> q = Queue()
>>> q.put(1)
>>> q.put(2)
>>> q.put(3)
>>> print list(q.queue)
[1, 2, 3]

Après l'opération, vous pouvez toujours les traiter:

>>> q.get()
1
>>> print list(q.queue)
[2, 3]
10
Omer Dagan

Vous pouvez sous-classer queue.Queue pour y parvenir de manière thread-safe:

import queue


class ImprovedQueue(queue.Queue):
    def to_list(self):
        """
        Returns a copy of all items in the queue without removing them.
        """

        with self.mutex:
            return list(self.queue)
6
Erwin Mayer