在說協程前,需要先了解在python中常用迭代器和生成器,了解這兩個能夠有效的幫助你去理解協程的工作原理
概念:通過for迴圈遍歷取值的過程叫迭代
可迭代物件:可用for迴圈遍歷取值的物件,[列表、元組、字典、集合、range、字串]
判斷方式:
匯入:form collections import iterable
判斷:result =
isinstance(資料,iterable[迭代物件型別]) 【返回boole值】
自定義迭代物件:
在類中定義__iter__方法建立的物件
注意:1.只要有__iter__方法的類建立的物件是可迭代物件,可迭代物件需要迭代器完成資料迭代
概念:在類裡定義__iter__和__next__方法建立的物件就是迭代器物件
優點:占用極小記憶體空間,儲存的是生成資料的方式而不是結果
實現:延遲計算 / 懶惰計算
判斷方式:
匯入:from collections import iterator
判斷:result = isinstance(資料,iterator[迭代器物件型別])
自定義迭代器:
iter()函式:獲取可迭代物件的迭代器,呼叫可迭代物件的__iter__方法
注意:1.迭代物件中的__iter__方法建立迭代器物件並返回
2.迭代器通過__next__獲取下乙個資料,資料取完後需要手動丟擲停止迭代的異常(raise stopiteration)
3.迴圈通過迭代器獲取資料時,需要進行異常捕獲,避免程式停止報錯
遍歷 可迭代物件
執行流程:for item in iterable
1.通過 iter() 函式獲取可迭代物件 iterable 的迭代器
2.對獲取的迭代器不斷呼叫 next() 方法獲取下乙個值並賦值給item
3.當遇到 stopiteration 的異常後迴圈結束
遍歷 迭代器
執行流程:for item in iterator
1.迴圈的迭代器不斷呼叫 next() 方法獲取下乙個值賦值給item
2.遇到stoplteration異常結束迴圈
應用場景:
迭代器的核心功能是通過next()函式呼叫返回下乙個資料值,如果資料**不是已有的集合中,而是通過程式按照一定規律生成,那麼可以不用依賴已有的資料集合,可以不用將所有要迭代的資料全部快取後依次讀取,可以節省大量的記憶體資源。
概念:不需要自己定義__iter__和__next__方法仍然可以使用next函式和for迴圈取值
場景:保證**只指定一部分就返回
建立:1.生成器表示式:將列表表示式的 [ ]更改為 () 【生成器儲存的是演算法,占用的記憶體更少】
2.函式生成器:使用了yield關鍵字
1.在yield下可以使用return,**執行到return時,會停止迭代,丟擲停止異常
【python3才支援 return 關鍵字,可以通過except stopiteration as e: 捕獲 e.value 輸出】
兩者之間區別:
1.使用了 yield 關鍵字的函式就是生成器
2.**執行到yield會暫停掛起,將結果返回給呼叫生成器的位置,下次啟動時從掛起位置繼續
3.每次啟動生成器都會返回乙個值,yield可以返回多個值
4.return只能返回一次值,**執行return 停止迭代
5.生成器的結束都是 stopiteration 異常丟擲,所以需要提前設定好捕獲
2.使用send方法啟動生成器傳參
異同:next是函式send是方法
next不能傳參send可以傳參
第一次呼叫必須是next,後續可以是send《傳遞的引數在yield左邊的變數獲取
send執行時也是從yield位置開始》
注意:1.單獨獲取生成器內容next(生成器物件)
2.for迴圈遍歷後,直接輸出結果,不需要next()】
概念: 微執行緒、使用者級執行緒,在def中有yield關鍵字就是協程
建立:1.greenlet
2.gevent(常用)
概述:內部封裝了greenlet,遇到io[input、output、網路、檔案操作]操作時,自動切換其他的greenlet,操作完成,再切換回來繼續執行
應用:1.匯入:from gevent import monkey
2.執行補丁:monkey.patch_all() 【使gevent識別耗時操作非同步執行處理,必須放在**開始處,避免載入問題】
3.建立協程物件:xx = gevent.spawn(方法名,位置引數(args),關鍵字引數(kwargs))
4.等待執行完成:xx.join() 【如果當前是無限迴圈且有耗時操作,可以不需要join】
5.批量程序等待:gevent.joinall([物件1],[物件2])
1.關聯
乙個程序至少有乙個執行緒,程序裡面可以有多個執行緒
乙個執行緒裡面可以 有多個協程
2.對比
1.程序是資源分配的基礎單位
2.執行緒是作業系統排程的基本單位
3.程序切換需要的資源最大,效率很低
4.執行緒切換需要的資源一般,效率一般(不基於gil的情況下)
5.執行緒切換任務資源很小,效率高
6.多程序、多執行緒根據cpu核數不一樣可能是並行,但是協程是乙個執行緒中,所以是併發
7.程序和執行緒都是由系統進行控制執行,而協程有程式設計師控制
8.程序適用於cpu密集不需要切換,大量併發計算的情況
9.多執行緒適用io密集,網路io和磁碟io
10.協程適用於:密集網路io,適合網路io
Python 程序 執行緒 協程
程序和執行緒之間的關係 執行緒是屬於程序的,執行緒執行在程序空間內,同一程序所產生的執行緒共享同一記憶體空間,當程序退出時該程序所產生的執行緒都會被強制退出並清除。執行緒可與屬於同一程序的其它執行緒共享程序所擁有的全部資源,但是其本身基本上不擁有系統資源,只擁有一點在執行中必不可少的資訊 如程式計數...
Python 程序,執行緒, 協程
程序是系統進行資源分配和排程的乙個獨立單位 最小單位 程序的幾個狀態 空 新建 建立執行乙個程式的新程序,可能的事件有 新的批處理作業 互動登入 終端使用者登入到系統 作業系統因為提供一項服務而建立 由現有的程序派生等。新建 就緒 作業系統準備好再接納乙個程序時,把乙個程序從新建態轉換為就緒態。就緒...
程序 執行緒與協程
程序的出現是為了更好的利用cpu資源使到併發成為可能。假設有兩個任務a和b,當a遇到io操作,cpu默默的等待任務a讀取完操作再去執行任務b,這樣無疑是對cpu資源的極大的浪費。聰明的老大們就在想若在任務a讀取資料時,讓任務b執行,當任務a讀取完資料後,再切換到任務a執行。注意關鍵字切換,自然是切換...