Introducción
El módulo estándar Queue o queue (Python 2 o 3, respectivamente) permite crear y trabajar con colas de manera sencilla. Es generalmente utilizado en programas multi-hilo, ya que provee una forma de intercambiar información entre threads de manera segura.
Implementa tres tipos de colas, que difieren únicamente en el orden en que se retornan los ítems:
- FIFO (primero en entrar primero en salir, del inglés «First In First Out»): el primer ítem que es añadido a la lista es el primero en ser retornado.
- LIFO (último en entrar primero en salir, del inglés «Last In First Out»): el último ítem que es añadido a la lista es el primero en ser retornado.
- Priority Queue (cola de prioridad): el ítem de menor valor es el primero en ser retornado.
Por lo tanto, cuenta con cinco clases: tres constructores (Queue
, LifoQueue
y PriorityQueue
) junto con dos excepciones (Empty
y Full
).
Los tres constructores toman como único parámetro opcional maxsize
, un entero que indica el límite de ítems en la cola. En caso de ser negativo o no indicarse, el tamaño de la cola es infinito.
Funciones
Todas las colas cuentan con 9 métodos públicos. A continuación, una breve descripción de cada uno. Véase la documentación del módulo para una información detallada.
qsize()
: retorna el tamaño aproximado de la cola.empty()
: retornaTrue
si la cola se encuentra vacía;False
de lo contrario.full()
: retornaTrue
si la cola se encuentra llena;Falso
de lo contrario.put(item, block=True, timeout=None)
: inserta item en la cola. Siblock
esTrue
,timeout
esNone
y la cola está llena, la función espera a que se libere un espacio para poder hacerlo. Sitimeout
es un número positivo, la función espera hasta dicho número en segundos y lanza la excepciónFull
si un espacio no se liberó en el lapso de tiempo. Siblock
esFalse
, insertaitem
si inmediatamente hay un espacio libre; de lo contrario, lanzaFull
.put_nowait(item)
: equivalente aput(item, False)
.get(block=True, timeout=None)
: remueve y retorna un ítem de la cola. Siblock
esTrue
,timeout
esNone
y la cola está vacía, la función espera a que haya un ítem disponible. Sitimeout
es un número positivo, la función espera hasta dicho número en segundos y lanza la excepciónEmpty
si no se encontró un ítem disponible en el lapso de tiempo. Siblock
esFalse
, retorna un ítem si se encuentra inmediatamente disponible; de lo contrario, lanzaEmpty
.-
get_nowait()
: equivalente aget(False)
. task_done()
: indica que una tarea de la cola se ha completado.join()
: bloquea la ejecución hasta que todos los ítems en la cola se hayan obtenido.
Los últimos dos métodos fueron añadidos en la versión 2.5 para el soporte de múltiples hilos.
Excepciones
La excepción Empty
es lanzada cuando se llama a get(False)
o get_nowait()
en una cola que se encuentra vacía. Análogamente, Full
es lanzada cuando se llama a put(item, False)
o put_nowait(item)
en una cola que ha alcanzado el número máximo de ítems (maxsize
).
Priority Queue
En las colas de prioridad los ítems generalmente se insertan como una tupla, a diferencia de las FIFO y LIFO, indicando el número en el primer lugar y los datos en el segundo. Por ejemplo:
(5, "Perro")
(10, "Gato")
(1, "Conejo")
Aplicados a una cola de este tipo serían retornados en el orden:
(1, 'Conejo')
(5, 'Perro')
(10, 'Gato')
Ya que el primer valor de la tupla indica su prioridad. Los ítems con menor prioridad serán los primeros en ser retornados.
Ejemplos
Ejemplo 1
Añadir y retornar tres ítems. Nótese el orden en el que se obtienen, variando según el tipo de cola.
try: import Queue as queue except ImportError: # Python 3 import queue fifo_queue = queue.Queue(3) lifo_queue = queue.LifoQueue(3) priority_queue = queue.PriorityQueue(3) fifo_queue.put("Perro") fifo_queue.put("Gato") fifo_queue.put("Conejo") lifo_queue.put("Perro") lifo_queue.put("Gato") lifo_queue.put("Conejo") priority_queue.put((2, "Perro")) priority_queue.put((3, "Gato")) priority_queue.put((1, "Conejo")) print("Cola FIFO") print(fifo_queue.get()) print(fifo_queue.get()) print(fifo_queue.get()) print("\nCola LIFO") print(lifo_queue.get()) print(lifo_queue.get()) print(lifo_queue.get()) print("\nCola de prioridad") print(priority_queue.get()) print(priority_queue.get()) print(priority_queue.get())
Imprime:
Cola FIFO
Perro
Gato
Conejo
Cola LIFO
Conejo
Gato
Perro
Cola de prioridad
(1, 'Conejo')
(2, 'Perro')
(3, 'Gato')
O una solución más óptima:
for cur_queue in (fifo_queue, lifo_queue, priority_queue): print("") print(cur_queue) for i in range(3): print(cur_queue.get())
Si se desconociera la cantidad de ítems, podría utilizarse:
for cur_queue in (fifo_queue, lifo_queue, priority_queue): print("") print(cur_queue) while True: try: item = cur_queue.get_nowait() except queue.Empty: # Ya se han retornado todos los ítems break else: print(item)
Ejemplo 2
Cómo esperar a que las tareas de la cola se completen (extraído de la documentación):
def worker(): while True: item = q.get() do_work(item) q.task_done() q = Queue() for i in range(num_worker_threads): t = Thread(target=worker) t.daemon = True t.start() for item in source(): q.put(item) q.join() # bloquear hasta que se completen las tareas
Versión
Python 2, Python 3
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter
en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.