Python高階——多執行緒_07_協程(修飾器)
迭代
概念:通過for迴圈遍歷取值的過程
可迭代物件:通過fo迴圈遍歷取值的物件
可迭代物件的本質:
遍歷可迭代物件的時候其實獲取的是可迭代物件的迭代器,
然後通過迭代器獲取物件中的資料
元組,列表,字典,字串,集合,range
迭代器
優點:佔用極小記憶體空間, 儲存的是生成資料的方式而不是結果
記錄當前資料的位置,方便取下一個位置的值
實現 延遲計算/懶惰計算
操作:
1.取出物件手元祖的位置資訊放入迭代器 返回迭代器
i = iter(data) iter返回迭代器 ==》可迭代物件.__iter__()
2.不斷通過迭代器去取出下一個元素的值 直到迭代完成
則丟擲異常 StopIteration 停止迭代異常
print(next(i)) next進行取值==》可迭代物件.__next__()
如果迭代完成則丟擲異常
raise StopIteration
自定義迭代器
1.使用__iter__提供迭代器 返回迭代器物件self
2.使用__next__提供下一個元素的值
判斷是否為迭代器
for collections import Iterator
isinstance(物件,Iterator) 返回True/False
判斷是否為迭代物件:for collections import Iterable
isinstance(物件,Iterable) 返回True/False
結論:
迭代器一定是可迭代物件
可迭代物件 不一定是迭代器 <可迭代物件只需要實現__iter__方法提供迭代器>
生成器
場景:保證程式碼只執行一部分就返回
概念:特殊的迭代器,不需要實現iter和next,仍然可以使用iter、next和for迴圈
分類
1.生成器表示式 列表推導式[]-->()
生成器表示式和列表推導式的異同:
不同:產生物件不同
生成器佔用記憶體更少,因為生成器儲存的是演算法
相同:使用結果一致
2.生成器函式
呼叫產生生成器物件
如果函式有yield語句,就是生成器模板
yield:
暫時掛起當前函式 將後面的值返回給呼叫生成器的地方
當再次呼叫生成器函式的時候 會回覆當前函式繼續執行
生成器內部自動實現
raise StopIteration __next__ __iter__
一般在生成器中不是用return 關鍵字
一旦使用就會結束生成器的迭代過程,獲取方式通過捕獲異常的value進行取值
使用send可以進行傳參
格式,生成器物件.send(引數)
第一次呼叫生成器必須使用next
通過傳入不同的引數可以控制生成器執行的邏輯
喚醒生成器
next(生成器物件)
生成器.send(資料)
異同:
next是函式 send是方法
next不能傳參 send可以傳參
第一次只能next 其餘地方隨意使用<引數的值只有yield才能接收>
因為send執行時必須從yield開始執行
同:
獲取到下一個元素的值
協程
輕量級執行緒
程序 執行緒 是作業系統級別的多工機制
協程是 使用者級別的多工機制<使用者程式自己實現>
使用場景:多工數量很多時/網路型程式
greenlet
對於yield的簡單封裝使用
通過switch進行切換
gevent
網路非同步併發庫
spawn(函式名,引數(args),引數(kwargs))建立協程
1.使用gevent.sleep進行自動切換
2.
【gevent文件規定 要求放在原始碼開始處】
form gevent import monkey
monkey.patch_all() #補丁
將預設阻塞變非阻塞:recv / accept / time.sleep
沒有設定前自動阻塞,不能切換
在所有協程之前完成前 保持主程序的存活
物件.join
gevent.joinall([物件1,物件2])