python queue_Python-Queue 入门
Queue 簡(jiǎn)介
Queue 叫隊(duì)列,是數(shù)據(jù)結(jié)構(gòu)中的一種,基本上所有成熟的編程語(yǔ)言都內(nèi)置了對(duì) Queue 的支持。
Python 中的 Queue 模塊實(shí)現(xiàn)了多生產(chǎn)者和多消費(fèi)者模型,當(dāng)需要在多線程編程中非常實(shí)用。而且該模塊中的 Queue 類實(shí)現(xiàn)了鎖原語(yǔ),不需要再考慮多線程安全問題
該模塊內(nèi)置了三種類型的 Queue,分別是class queue.Queue(maxsize=0),class queue.LifoQueue(maxsize=0)和class queue.PriorityQueue(maxsize=0)。它們?nèi)齻€(gè)的區(qū)別僅僅是取出時(shí)的順序不一致而已。
Queue 是一個(gè) FIFO 隊(duì)列,任務(wù)按照添加的順序被取出。
LifoQueue 是一個(gè) LIFO 隊(duì)列,類似堆棧,后添加的任務(wù)先被取出。
PriorityQueue 是一個(gè)優(yōu)先級(jí)隊(duì)列,隊(duì)列里面的任務(wù)按照優(yōu)先級(jí)排序,優(yōu)先級(jí)高的先被取出。
Queue 常用操作
類和異常
1 class queue.Queue(maxsize=0)2 class queue.LifoQueue(maxsize=0)3 class queue.PriorityQueue(maxsize=0)
如你所見,就是上面所說的三種不同類型的內(nèi)置隊(duì)列,其中 maxsize 是個(gè)整數(shù),用于設(shè)置可以放入隊(duì)列中的任務(wù)數(shù)的上限。當(dāng)達(dá)到這個(gè)大小的時(shí)候,插入操作將阻塞至隊(duì)列中的任務(wù)被消費(fèi)掉。如果 maxsize 小于等于零,則隊(duì)列尺寸為無(wú)限大。
1 exception queue.Empty2 #對(duì)空的 Queue 對(duì)象調(diào)用非阻塞的 get() (or get_nowait()) 時(shí),會(huì)引發(fā)該異常。
3
4 exception queue.Full5 #對(duì)滿的 Queue 對(duì)象調(diào)用非阻塞的 put() (or put_nowait()) 時(shí),會(huì)引發(fā)該異常。
常用操作
添加任務(wù)
向隊(duì)列中添加任務(wù),直接調(diào)用put()函數(shù)即可
1 importqueue2 >>> q = queue.Queue(maxsize=1)3 >>> q.put(100)
put()函數(shù)完整的函數(shù)簽名如下Queue.put(item, block=True, timeout=None),如你所見,該函數(shù)有兩個(gè)可選參數(shù)。
默認(rèn)情況下,在隊(duì)列滿時(shí),該函數(shù)會(huì)一直阻塞,直到隊(duì)列中有空余的位置可以添加任務(wù)為止。如果 timeout 是正數(shù),則最多阻塞 timeout 秒,如果這段時(shí)間內(nèi)還沒有空余的位置出來,則會(huì)引發(fā)Full異常。
1 >>> importqueue2 >>> q = queue.Queue(maxsize=1)3 >>> q.put(100)4 >>> q.put(100,True,2)5 Traceback (most recent call last):6 File "", line 1, in
7 File "E:\Python37-32\lib\queue.py", line 147, input8 raiseFull9 queue.Full #創(chuàng)建一個(gè)容量為 1 的隊(duì)列,2 秒內(nèi)沒有位置添加任務(wù)則引發(fā) Full 異常
10 >>> q.put(100) #該方法會(huì)一直阻塞
當(dāng) block 為 false 時(shí),timeout 參數(shù)將失效。同時(shí)如果隊(duì)列中沒有空余的位置可添加任務(wù)則會(huì)引發(fā)Full異常,否則會(huì)直接把任務(wù)放入隊(duì)列并返回,不會(huì)阻塞。
1 >>> importqueue2 >>> q = queue.Queue(maxsize=1)3 >>> q.put(100)4 >>> q.put(100,False,2)5 Traceback (most recent call last):6 File "", line 1, in
7 File "E:\Python37-32\lib\queue.py", line 136, input8 raiseFull9 queue.Full10 #創(chuàng)建一個(gè)容量為 1 的隊(duì)列,在第二次放入任務(wù)時(shí)指定為非阻塞模式,則會(huì)立刻引發(fā) Full 異常
另外,還可以通過Queue.put_nowait(item)來添加任務(wù),相當(dāng)于Queue.put(item, False),不再贅述。同樣,在隊(duì)列滿時(shí),該操作會(huì)引發(fā)Full異常。
獲取任務(wù)
從隊(duì)列中獲取任務(wù),直接調(diào)用get()函數(shù)即可
1 >>> importqueue2 >>> q =queue.Queue()3 >>> q.put(100)4 >>>q.get()5 100
與put()函數(shù)一樣,get()函數(shù)也有兩個(gè)可選參數(shù),完整簽名如下Queue.get(block=True, timeout=None)。
默認(rèn)情況下,當(dāng)隊(duì)列空時(shí)調(diào)用該函數(shù)會(huì)一直阻塞,直到隊(duì)列中有任務(wù)可獲取為止。如果 timeout 是正數(shù),則最多阻塞 timeout 秒,如果這段時(shí)間內(nèi)還沒有任務(wù)可獲取,則會(huì)引發(fā)Empty異常。
1 >>> importqueue2 >>> q =queue.Queue()3 >>> q.put(100)4 >>>q.get()5 100
6 >>> q.get(True,2)7 Traceback (most recent call last):8 File "", line 1, in
9 File "E:\Python37-32\lib\queue.py", line 178, inget10 raiseEmpty11 _queue.Empty #2 秒鐘內(nèi)沒有任務(wù)可獲取則引發(fā) Empty 異常
12 >>> q.get() #該方法會(huì)一直阻塞
當(dāng) block 為 false 時(shí),timeout 參數(shù)將失效。同時(shí)如果隊(duì)列中沒有任務(wù)可獲取則會(huì)立刻引發(fā)Empty異常,否則會(huì)直接獲取一個(gè)任務(wù)并返回,不會(huì)阻塞。
1 >>> importqueue2 >>> q =queue.Queue()3 >>> q.put(100)4 >>>q.get()5 100
6 >>> q.get(False,2)7 Traceback (most recent call last):8 File "", line 1, in
9 File "E:\Python37-32\lib\queue.py", line 167, inget10 raiseEmpty11 _queue.Empty12 #指定為非阻塞模式,隊(duì)列為空則立即引發(fā) Empty 異常
另外,還可以通過Queue.get_nowait()來獲取任務(wù),相當(dāng)于Queue.get(False),不再贅述。同樣,在隊(duì)列為空時(shí),該操作會(huì)引發(fā)Empty異常。
其他常用方法
獲取隊(duì)列大小
1 >>> importqueue2 >>> q =queue.Queue()3 >>> q.put(100)4 >>> q.put(200)5 >>>q.qsize()6 2
判斷隊(duì)列是否空
如果隊(duì)列為空,返回True,否則返回False。如果 empty() 返回True,不保證后續(xù)調(diào)用的 put() 不被阻塞。類似的,如果 empty() 返回False,也不保證后續(xù)調(diào)用的 get() 不被阻塞。
判斷隊(duì)列是否滿
如果隊(duì)列是滿的返回True,否則返回False。如果 full() 返回True不保證后續(xù)調(diào)用的 get() 不被阻塞。類似的,如果 full() 返回False也不保證后續(xù)調(diào)用的 put() 不被阻塞。
1 >>> importqueue2 >>> q = queue.Queue(maxsize=1)3 >>>q.empty()4 True5 >>>q.full()6 False7 >>> q.put(100)8 >>>q.empty()9 False10 >>>q.full()11 True
隊(duì)列對(duì)比
FIFO 隊(duì)列
queue.Queue()是 FIFO 隊(duì)列,出隊(duì)順序跟入隊(duì)順序是一致的。
1 importqueue2 q =queue.Queue()3 for index in range(10):4 q.put(index)5 while notq.empty():6 print(q.get(), end=",")7 ## 輸出結(jié)果如下
8 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
LIFO 隊(duì)列
queue.LifoQueue()是 LIFO 隊(duì)列,出隊(duì)順序跟入隊(duì)順序是完全相反的,類似于棧。
importqueue
q= queue.LifoQueue() #創(chuàng)建一個(gè) LIFO 隊(duì)列
for index in range(10):
q.put(index)while notq.empty():print(q.get(), end=",")## 輸出結(jié)果如下
9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
優(yōu)先級(jí)隊(duì)列
優(yōu)先級(jí)隊(duì)列中的任務(wù)順序跟放入時(shí)的順序是無(wú)關(guān)的,而是按照任務(wù)的大小來排序,最小值先被取出。那任務(wù)比較大小的規(guī)則是怎么樣的呢。
如果是內(nèi)置類型,比如數(shù)值或者字符串,則按照自然順序來比較排序。
importqueue
q=queue.PriorityQueue()for index in range(10,0,-1):
q.put(index)while notq.empty():print(q.get(), end=",")## 輸出結(jié)果如下
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
如果是列表或者元祖,則先比較第一個(gè)元素,然后比較第二個(gè),以此類推,直到比較出結(jié)果
importqueue
q=queue.PriorityQueue()
q.put(["d","b"])
q.put(["c","b"])while notq.empty():print(q.get(), end=",")## 輸出結(jié)果如下
['c', 'b'], ['d', 'b'],
注意,因?yàn)榱斜淼谋容^對(duì)規(guī)則是按照下標(biāo)順序來比較的,所以在沒有比較出大小之前 ,隊(duì)列中所有列表對(duì)應(yīng)下標(biāo)位置的元素類型要一致。
好比[2,1]和["1","b"]因?yàn)榈谝粋€(gè)位置的元素類型不一樣,所以是沒有辦法比較大小的,所以也就放入不了優(yōu)先級(jí)隊(duì)列。
然而對(duì)于[2,1]和[1,"b"]來說即使第二個(gè)元素的類型不一致也是可以放入優(yōu)先級(jí)隊(duì)列的,因?yàn)橹恍枰容^第一個(gè)位置元素的大小就可以比較出結(jié)果了,就不需要比較第二個(gè)位置元素的大小了。
但是對(duì)于[2,1]和 1[2,"b"]來說,則同樣不可以放入優(yōu)先級(jí)隊(duì)列,因?yàn)樾枰容^第二個(gè)位置的元素才可以比較出結(jié)果,然而第二個(gè)位置的元素類型是不一致的,無(wú)法比較大小。
綜上,也就是說,直到在比較出結(jié)果之前,對(duì)應(yīng)下標(biāo)位置的元素類型都是需要一致的。
如果是自定義類型,需要實(shí)現(xiàn)__lt__比較函數(shù)
下面我們自定義一個(gè)動(dòng)物類型,希望按照年齡大小來做優(yōu)先級(jí)排序。年齡越小優(yōu)先級(jí)越高。
importqueue
q=queue.PriorityQueue()classAnimal:def __init__(self, age, name):
self.age=age
self.name=namedef __lt__(self, other): #實(shí)現(xiàn) < 操作
return self.age < other.age #如果將 < 變成 > 則相當(dāng)于逆序
q.put(Animal(3,"cat"))
q.put(Animal(2,"dog"))while notq.empty():
animal=q.get()print(animal.name, animal.age, end=",")## 輸出結(jié)果如下
dog 2, cat 3,
總結(jié)
以上是生活随笔為你收集整理的python queue_Python-Queue 入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 文件大小_linux系统中查
- 下一篇: java redis 批量删除key_R