Python 的队列模块中的栈和队列
在 Python 中,实现栈和队列数据结构非常容易。栈被称为 LIFO(后进先出),因为栈遵循“后进先出”的原则;队列被称为 FIFO(先进先出),因为队列遵循“先进先出”的原则。Python 的内置函数使代码更短更简洁。
Queue 模块实现了多生产者、多消费者队列,它在多线程编程中特别有用,此时需要在多个线程之间安全地交换信息。此模块中的 Queue 类实现了所有必要的锁定语义,并且它依赖于 Python 中线程支持的可用性。
此模块实现了三种类型的队列,它们的区别仅在于检索条目的顺序。对于 FIFO 队列,首先添加的任务是首先检索的任务;对于 LIFO 队列,最近添加的条目是首先检索的条目(类似于栈的操作)。对于优先级队列,条目保持排序(使用 heapq 模块),并且首先检索值最低的条目。
此队列模块定义了以下类和异常。
class Queue.Queue(maxsize=0)
这是 FIFO 队列的构造函数。参数 maxsize 是一个整数,它设置可以放入队列中的项目数量的上限。一旦达到此大小,插入将被阻塞,直到队列项目被使用。如果 maxsize 小于或等于零,则队列大小将是无限的。
class Queue.LifoQueue(maxsize=0)
这是 LIFO 队列的构造函数。参数 maxsize 是一个整数,它设置可以放入队列中的项目数量的上限。一旦达到此大小,插入将被阻塞,直到队列项目被使用。如果 maxsize 小于或等于零,则队列大小将是无限的。
class Queue.PriorityQueue(maxsize=0)
这是优先级队列的构造函数。参数 maxsize 是一个整数,它设置可以放入队列中的项目数量的上限。一旦达到此大小,插入将被阻塞,直到队列项目被使用。如果 maxsize 小于或等于零,则队列大小是无限的。
exception Queue.Empty
当在空队列对象上调用非阻塞 get()(或 get_nowait())时,此行表示引发的异常。
exception Queue.Full
此行表示当在已满的队列对象上调用非阻塞 put()(或 put_nowait())时引发的异常。
队列对象
Queue.qsize()
此函数返回队列的大致大小。
Queue.empty()
如果队列为空,此函数返回 True,否则返回 False。如果 empty() 返回 True,它并不保证随后对 put() 的调用不会阻塞。类似地,如果 empty() 返回 False,它并不保证随后对 get() 的调用不会阻塞。
Queue.full()
如果队列已满,则返回 True,否则返回 False。如果 full() 返回 True,它并不保证随后对 get() 的调用不会阻塞。类似地,如果 full() 返回 False,它并不保证随后对 put() 的调用不会阻塞。
Queue.put(item[, block[, timeout]])
将项目放入队列。如果可选参数 block 为 true 且 timeout 为 None(默认值),则在必要时阻塞,直到有空闲槽可用。如果 timeout 是一个正数,它最多阻塞 timeout 秒,如果在此时间内没有空闲槽可用,则引发 Full 异常。否则(block 为 false),如果立即有空闲槽可用,则将项目放入队列,否则引发 Full 异常(在这种情况下忽略 timeout)。
Queue.get([block[, timeout]])
从队列中移除并返回一个项目。如果可选参数 block 为 true 且 timeout 为 None(默认值),则在必要时阻塞,直到有项目可用。如果 timeout 是一个正数,它最多阻塞 timeout 秒,如果在此时间内没有项目可用,则引发 Empty 异常。否则(block 为 false),如果立即有项目可用,则返回一个项目,否则引发 Empty 异常(在这种情况下忽略 timeout)。
Queue.task_done()
指示先前排队的任务已完成。由队列使用者线程使用。对于每个用于获取任务的 get(),后续对 task_done() 的调用告诉队列任务的处理已完成。
如果 join() 目前正在阻塞,则当所有项目都已处理完毕后(这意味着为放入队列中的每个项目都收到了 task_done() 调用),它将恢复。
如果调用的次数超过放入队列中的项目数量,则引发 ValueError。
Queue.join()
阻塞,直到队列中的所有项目都已获取并处理完毕。
每当项目添加到队列时,未完成任务的数量就会增加。每当使用者线程调用 task_done() 以指示已检索到项目并且其所有工作都已完成时,计数就会减少。当未完成任务的数量降为零时,join() 将取消阻塞。
示例代码
import queue #maximum capacity of queue is 20 Q = queue.Queue(maxsize=40) Q.put(50) Q.put(90) Q.put(10) Q.put(70) print(Q.get()) print(Q.get()) print(Q.get()) print(Q.get())
输出
50 90 10 70
下溢/上溢示例
import queue Q = queue.Queue(maxsize=30) print(Q.qsize()) Q.put(50) Q.put(90) Q.put(10) Q.put(70) print("Full: ", Q.full()) Q.put(90) Q.put(100) print("Full: ", Q.full()) print(Q.get()) print(Q.get()) print(Q.get()) print("Empty: ", Q.empty()) print(Q.get()) print(Q.get()) print(Q.get()) print("Empty: ", Q.empty()) print("Full: ", Q.full())
输出
0 Full: False Full: False 50 90 10 Empty: False 70 90 100 Empty: True Full: False
栈的示例 3
import queue S = queue.LifoQueue(maxsize=10) # qsize() give the maxsize of # the Queue print(S.qsize()) S.put(50) S.put(90) S.put(10) S.put(70) S.put(90) S.put(10) print("Full: ", S.full()) print("Size: ", S.qsize()) # Data will be accessed in the # reverse order Reverse of that # of Queue print(S.get()) print(S.get()) print(S.get()) print(S.get()) print(S.get()) print("Empty: ", S.empty())
输出
0 Full: False Size: 6 10 90 70 10 90 Empty: False