理解Python中的yield以及協(xié)程

要理解yield,必須先清楚可迭代對(duì)象藻丢、迭代器和生成器的概念犁跪。

一、可迭代對(duì)象

大部分對(duì)象都是可迭代法希,只要實(shí)現(xiàn)了__iter__方法的對(duì)象(可以是自定義的容器)就是可迭代的,例如常見(jiàn)的list枷餐、tuple、str, set苫亦。
__iter__方法會(huì)返回迭代器(iterator)本身毛肋。
判斷一個(gè)對(duì)象是否是可迭代對(duì)象的方法:
isinstance(Object, Iterable)
可迭代對(duì)象一般都用for循環(huán)遍歷元素,也就是能用for循環(huán)的對(duì)象都可稱為可迭代對(duì)象, 如何對(duì)非可迭代對(duì)象使用for會(huì)報(bào)錯(cuò)屋剑。
可迭代對(duì)象生成后, 所有的值都存在內(nèi)存當(dāng)中,并不適合大量數(shù)據(jù)润匙。

二、迭代器

具有next方法的對(duì)象都是迭代器唉匾。在調(diào)用next方法時(shí)孕讳,迭代器會(huì)返回它的下一個(gè)值匠楚。如果next方法被調(diào)用,但迭代器沒(méi)有值可以返回厂财,就會(huì)引發(fā)一個(gè)StopIteration異常,通過(guò)except 這個(gè)異秤蟛荆可以判斷迭代器遍歷完成。

使用迭代器的好處:

1)如果使用列表璃饱,計(jì)算值時(shí)會(huì)一次獲取所有值与斤,那么就會(huì)占用更多的內(nèi)存。而迭代器則是一個(gè)接一個(gè)計(jì)算荚恶。
2)使代碼更通用撩穿、更簡(jiǎn)單。

三谒撼、生成器

1)任何包含yield語(yǔ)句的函數(shù)都稱為生成器食寡。
2)生成器都是一個(gè)迭代器,但迭代器不一定是生成器嗤栓。
對(duì)于生成器, 只有你需要的時(shí)候它才會(huì)求值, 這也是和可迭代對(duì)象的區(qū)別冻河。
3 ) 一般生成器都是通過(guò)生成器推導(dǎo)式或者包含yield的函數(shù)聲明
----生成器推導(dǎo)式和組建:

變量L= (item或item表達(dá)式 for item in 列表/集合)

# 通過(guò)`yield`來(lái)創(chuàng)建生成器
def func():
   for i in xrange(10);
        yield i

# 通過(guò)列表來(lái)創(chuàng)建生成器
[i for i in xrange(10)]

4 ) 帶有 yield 的函數(shù)不再是一個(gè)普通函數(shù),而是一個(gè)生成器generator茉帅,可用于迭代叨叙。


yield的作用:

1.它和return差不多的用法,只是擁有它的語(yǔ)法結(jié)構(gòu)最后是返回了一個(gè)生成器堪澎。
2.了解yield 必須知道擂错,當(dāng)你調(diào)用yield所在的那個(gè)函數(shù)或者生成器表達(dá)式的時(shí)候,那個(gè)函數(shù)并沒(méi)有運(yùn)行樱蛤,只會(huì)返回一個(gè)生成器的對(duì)象钮呀。
3.當(dāng)你第一次在for中調(diào)用生成器的的對(duì)象,它將會(huì)運(yùn)行你函數(shù)中的代碼從最開始一直到到碰到了yield的關(guān)鍵字昨凡,然后它會(huì)返回循環(huán)中的第一個(gè)值爽醋。然后每一次其他的調(diào)用將會(huì)運(yùn)行你在這個(gè)函數(shù)中所寫的循環(huán)多一次(第二次循環(huán)從第一次返回的yield位置后面開始到遇到下一個(gè)yield)调榄,并且返回下一個(gè)值朝蜘,直到?jīng)]有值可以返回了,此時(shí)迭代器遍歷完成。


與生成器(實(shí)際上是迭代器)相關(guān)的next()和send()方法:

生成器可以被for調(diào)用, 也可以使用send和next方法手動(dòng)進(jìn)行遍歷控制,實(shí)現(xiàn)更復(fù)雜的功能跨琳。

對(duì)于普通的生成器哪痰,第一個(gè)next調(diào)用遂赠,相當(dāng)于啟動(dòng)生成器,會(huì)從生成器函數(shù)的第一行代碼開始執(zhí)行晌杰,直到第一次執(zhí)行完yield語(yǔ)句

send(msg)與next()都有返回值跷睦,它們的返回值是當(dāng)前迭代遇到y(tǒng)ield時(shí),yield后面表達(dá)式的值肋演,其實(shí)就是當(dāng)前迭代循環(huán)()中yield后面的參數(shù)抑诸。

第一次調(diào)用時(shí)必須先next()或send(None)烂琴,否則會(huì)報(bào)錯(cuò),send后之所以為None是因?yàn)檫@時(shí)候沒(méi)有上一個(gè)yield(根據(jù)第8條)哼鬓〖嘤遥可以認(rèn)為边灭,next()等同于send(None)异希。

區(qū)別是:

send可以強(qiáng)行修改上一個(gè)yield表達(dá)式值, 多了一次賦值的動(dòng)作。
send語(yǔ)句伴隨著類似n1 = yield ret的結(jié)構(gòu), 旨在從循環(huán)外傳入數(shù)據(jù)而影響循環(huán)绒瘦。
注意, 從第二次循環(huán)開始, send語(yǔ)句傳遞賦值到 n1 然后繼續(xù)執(zhí)行循環(huán)并遇到下一個(gè)yield称簿。
具體流程參考


python中yield控制的協(xié)程

協(xié)程是一種用戶態(tài)的輕量級(jí)線程,又稱微線程惰帽,英文名Coroutine憨降,本質(zhì)上還是一個(gè)線程, 擁有線程的共享代碼段(代碼和常量),數(shù)據(jù)段(全局變量和靜態(tài)變量)该酗,擴(kuò)展段(堆存儲(chǔ))授药。協(xié)程的調(diào)度完全由用戶控制。人們通常將協(xié)程和子程序(函數(shù))比較著理解呜魄。

子程序調(diào)用總是一個(gè)入口悔叽,一次返回,一旦退出即完成了子程序的執(zhí)行爵嗅。
協(xié)程的起始處是第一個(gè)入口點(diǎn)娇澎,在協(xié)程里,返回點(diǎn)之后是接下來(lái)的入口點(diǎn)睹晒。在python中趟庄,協(xié)程可以通過(guò)yield來(lái)調(diào)用其它協(xié)程。通過(guò)yield方式轉(zhuǎn)移執(zhí)行權(quán)的協(xié)程之間不是調(diào)用者與被調(diào)用者的關(guān)系伪很,而是彼此對(duì)稱戚啥、平等的,通過(guò)相互協(xié)作共同完成任務(wù)锉试。其運(yùn)行的大致流程如下:

  • 第一步猫十,協(xié)程A開始執(zhí)行。
  • 第二步键痛,協(xié)程A執(zhí)行到一半炫彩,進(jìn)入暫停(這里是生成器完成一次生成),通過(guò)yield命令將執(zhí)行權(quán)轉(zhuǎn)移到協(xié)程B絮短。
  • 第三步江兢,(一段時(shí)間后)協(xié)程B交還執(zhí)行權(quán)并傳遞信息給下一次生成循環(huán)(send方法)。
  • 第四步丁频,協(xié)程A恢復(fù)執(zhí)行杉允。

yield from用于生成器嵌套

具體可以參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末邑贴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子叔磷,更是在濱河造成了極大的恐慌拢驾,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件改基,死亡現(xiàn)場(chǎng)離奇詭異繁疤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)秕狰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門稠腊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鸣哀,你說(shuō)我怎么就攤上這事架忌。” “怎么了我衬?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵叹放,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我挠羔,道長(zhǎng)井仰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任褥赊,我火速辦了婚禮糕档,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拌喉。我一直安慰自己速那,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布尿背。 她就那樣靜靜地躺著端仰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪田藐。 梳的紋絲不亂的頭發(fā)上荔烧,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音汽久,去河邊找鬼鹤竭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛景醇,可吹牛的內(nèi)容都是我干的臀稚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼三痰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吧寺!你這毒婦竟也來(lái)了窜管?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤稚机,失蹤者是張志新(化名)和其女友劉穎幕帆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赖条,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡失乾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谋币。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仗扬。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蕾额,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情彼城,我是刑警寧澤诅蝶,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站募壕,受9級(jí)特大地震影響调炬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舱馅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一缰泡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧代嗤,春花似錦棘钞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至硝逢,卻和暖如春姨拥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背渠鸽。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工叫乌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徽缚。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓憨奸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親猎拨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膀藐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Coroutine in Python 引言: 本文出自David Beazley 的關(guān)于協(xié)程的PPT屠阻,現(xiàn)在筆者將...
    LumiaXu閱讀 1,603評(píng)論 4 8
  • 這幾天看了看操作系統(tǒng),順便研究了一下Python的協(xié)程额各,下面就是做的一點(diǎn)筆記 協(xié)程是什么? 協(xié)程国觉,英文Corout...
    Miracle778閱讀 2,855評(píng)論 0 4
  • 基于生成器的協(xié)程 生成器可以作為協(xié)程(coroutine)使用傲醉,稱為 "基于生成器的協(xié)程"蝇闭。協(xié)程和生成器類似,都是...
    Alcazar閱讀 849評(píng)論 0 4
  • 排版能力硬毕,是平面設(shè)計(jì)師呻引,一個(gè)比較重要的能力,實(shí)際操作最多的技能吐咳。 為了好好回顧設(shè)計(jì)基礎(chǔ)理論知識(shí)逻悠,看書,看知識(shí)整理韭脊,...
    小云繪閱讀 1,767評(píng)論 4 48
  • 北京女子圖鑒有感 這部電視劇我已經(jīng)期待已久童谒,這部電視劇打著北漂的旗號(hào),利用著最具有吸引眼球的詞語(yǔ)沪羔。我只能說(shuō)饥伊,這是很...
    休憩站閱讀 329評(píng)論 0 0