def g_01():
print('---g_01-01---') #代碼執(zhí)行位置標(biāo)記
point_01=yield
print('---g_01-02---')
for _ in range(5):
print('---g_01---:{}'.format(point_01))
def main_01():
g=g_01()
print('---main_01-01---') #代碼執(zhí)行位置標(biāo)記
g.send(None) #我們的核心:預(yù)激生成器
print('---main_01-02---')
g.send('Android')
'''
執(zhí)行:
main_01()
輸出結(jié)果:
---main_01-01---
---g_01-01--- 我們執(zhí)行完成預(yù)先預(yù)激生成器后梢为,生成器g_01執(zhí)行到 ---g_01-01---位置
---main_01-02--- 從生成器返回調(diào)用函數(shù) main_01
---g_01-02--- 通過調(diào)用者main_01,我們send('android'),向生成器傳送一個值,生成器接受這個值仲器,并向下執(zhí)行
---g_01---:Android 執(zhí)行生成器代碼
---g_01---:Android 執(zhí)行生成器代碼
---g_01---:Android 執(zhí)行生成器代碼
---g_01---:Android 執(zhí)行生成器代碼
---g_01---:Android 執(zhí)行生成器代碼
StopIteration 生成器代碼執(zhí)行完畢藐鹤,出發(fā)StopIteration異常穴吹,拋給send方法的調(diào)用者main_01函數(shù)
'''
'''
所以,我們不能在預(yù)激線程的代碼中傳入數(shù)據(jù)应媚,應(yīng)為那時生成器的代碼還沒執(zhí)行到y(tǒng)ield的位置,只有預(yù)激生成器规肴,
讓生成器執(zhí)行到y(tǒng)ield前停住。往后我們調(diào)用send傳入數(shù)據(jù)胯府,此時生成器才能接受我們傳入的值
下面我們驗證下
'''
def main_02():
g=g_01()
print('---main_01-01---') #代碼執(zhí)行位置標(biāo)記
# g.send(None) #我們的核心:預(yù)激生成器
print('---main_01-02---')
g.send('Android')
'''
執(zhí)行:
main_02()
輸出結(jié)果:
---main_01-01---
---main_01-02--- #我們?nèi)∠藗魉蛃end(None),生成器開始到第一個yield之間的代碼沒有執(zhí)行
Traceback (most recent call last):
File "/home/qing/PythonWebApp/02_異步IO/02_asyncio案例/關(guān)于預(yù)激線程的探討.py", line 48, in <module>
main_02()
File "/home/qing/PythonWebApp/02_異步IO/02_asyncio案例/關(guān)于預(yù)激線程的探討.py", line 42, in main_02
g.send('Android')
TypeError: can't send non-None value to a just-started generator
所以,我們預(yù)激生成器的意義是將代碼生成器代碼在神奇的yield位置停住,這個生成器創(chuàng)建代碼并不會將代碼執(zhí)行到y(tǒng)ield位置)腌乡,生成器準(zhǔn)備接受參數(shù)
'''
'''
或許大家會對生成器到底是在yield的前面停住盟劫,還是在yield執(zhí)行過程中停住這個問題有疑問夜牡,
下面我們來看下這兩個例子,來看下生成器是如何執(zhí)行yield的
'''
def gen_01():
print('gen_01--before y1--')
y1=yield 'yield_y1'
print('gen_01--after y1:{}--'.format(y1))
print('gen_01--before y2--')
y2=yield 'yield_y2'
print('gen_01--after y2:{}--'.format(y2))
print('gen_01--before y3--')
y3=yield 'yield_y3'
print('gen_01--after y3:{}--'.format(y3))
return 'jet'
def main_01():
g=gen_01()
print('main_01--before s1--')
s1=g.send(None)
print('main_01--after s1:{}--'.format(s1))
print('main_01--before s2--')
s2=g.send('send_s2')
print('main_01--after s2:{}--'.format(s2))
print('mian_01--before s3--')
s3=g.send('send_s3')
print('main_03--after s3:{}--'.format(s3))
print('main_01--before s4--')
s4=None
try:
s4=g.send('s4')
print('main_01--stop iteration:{}--'.format(s4))
except StopIteration as e:
print('main_01--Exception_StopIteration:{} --'.format(e))
'''
執(zhí)行:
main_01()
輸出結(jié)果:
main_01--before s1--
gen_01--before y1--
我們在調(diào)用者main中調(diào)用send預(yù)激生成器,然后程序跳到生成器中執(zhí)行,
生成器件執(zhí)行到第一個yiled出停住,第一個yield右邊的值返回給調(diào)用者main与纽,程序跳回main執(zhí)行
main_01--after s1:yield_y1--
main_01--before s2--
調(diào)用者main接受生成器yield過來的參數(shù),繼續(xù)往下執(zhí)行塘装,直達(dá)執(zhí)行到第二個send,程序跳轉(zhuǎn)到生成器中執(zhí)行
gen_01--after y1:send_s2--
gen_01--before y2--
生成器從第一個卡住的yield位置向下執(zhí)行急迂,接收調(diào)用者main函數(shù)send過來的參數(shù),然后繼續(xù)往下執(zhí)行,直到遇到二個yield,將第二個yield右邊的值返回給調(diào)用者main,程序跳回main執(zhí)行
main_01--after s2:yield_y2--
mian_01--before s3--
調(diào)用者main接受生成器yield過來的參數(shù),繼續(xù)向下執(zhí)行蹦肴,直到執(zhí)行到第三個send,程序跳轉(zhuǎn)到生成器中執(zhí)行
gen_01--after y2:send_s3--
gen_01--before y3--
生成器從第二個卡住的yield位置向下執(zhí)行僚碎,接受調(diào)用者main函數(shù)send過來的參數(shù),然后繼續(xù)向下執(zhí)行阴幌,直到遇到第三個yield勺阐,將第三個yield右邊的值返回給調(diào)用者main,程序跳回main執(zhí)行
main_03--after s3:yield_y3--
main_01--before s4--
調(diào)用者main接受生成器yield過來的參數(shù),繼續(xù)向下執(zhí)行矛双,直到執(zhí)行到第四個send渊抽,程序跳轉(zhuǎn)到生成器中執(zhí)行
gen_01--after y3:s4--
生成器從第三個卡住的yield位置向下執(zhí)行,接受調(diào)用者main函數(shù)send過來的參數(shù)议忽,然后繼續(xù)向下執(zhí)行懒闷,直達(dá)全部執(zhí)行完畢(return 'jet'),
然后向上拋出StopIteration(這個異常的__str__返回'jet'的__str__,如果沒有返回值栈幸,這個異常的__str__返回""),調(diào)用者main充當(dāng)StopIteration的接盤俠
main_01--Exception_StopIteration:jet --
調(diào)用者main函數(shù)愤估,捕獲異常并執(zhí)行接下來的代碼,直到執(zhí)行完畢
'''
def gen_02():
print('gen_02--before y1--')
y1=yield 'yield_y1'
print('gen_02--after y1:{}--'.format(y1))
print('gen_02--before y2--')
y2=yield 'yield_y2'
print('gen_02--after y2:{}--'.format(y2))
print('gen_02--before y3--')
y3=yield 'yield_y3'
print('gen_02--after y3:{}--'.format(y3))
def main_02():
g=gen_02()
print('main_02--before s1--')
s1=g.send(None)
print('main_02--after s1:{}--'.format(s1))
print('main_02--before s2--')
s2=g.send('send_s2')
print('main_02--after s2:{}--'.format(s2))
print('mian_02--before s3--')
s3=g.send('send_s3')
print('main_02--after s3:{}--'.format(s3))
print('main_02--before s4--')
s4=None
try:
s4=g.send('s4')
print('main_02--stop iteration:{}--'.format(s4))
except StopIteration as e:
print('main_02--Exception_StopIteration:{} --'.format(e))
'''
執(zhí)行:
main_02()
輸出:
main_02--before s1--
gen_02--before y1--
main_02--after s1:yield_y1--
main_02--before s2--
gen_02--after y1:send_s2--
gen_02--before y2--
main_02--after s2:yield_y2--
mian_02--before s3--
gen_02--after y2:send_s3--
gen_02--before y3--
main_02--after s3:yield_y3--
main_02--before s4--
gen_02--after y3:s4--
生成器從第三個卡住的yield位置向下執(zhí)行,接受調(diào)用者main函數(shù)send過來的參數(shù)速址,然后繼續(xù)向下執(zhí)行玩焰,直達(dá)全部執(zhí)行完畢,
然后向上拋出StopIteration(這個生成器沒有return返回值,則異常的__str__返回“”),調(diào)用者main充當(dāng)StopIteration的接盤俠
main_02--Exception_StopIteration: --
調(diào)用者main函數(shù),捕獲異常并執(zhí)行接下來的所有代碼
'''
'''
寫在最后:
調(diào)用者調(diào)用生成器的send芍锚,
如果是第一次調(diào)用
會從生成器代碼的開始一直運行到遇到的第一個yield昔园,并將yield右邊的值返回給調(diào)用者荔棉,停在yield,程序執(zhí)行由生成器代碼切換到調(diào)用者代碼
如果是普通情況下的調(diào)用
會跳掉生成器代碼執(zhí)行,生成器從當(dāng)前卡住的yield開始將接受send的參數(shù)蒿赢,并繼續(xù)往下執(zhí)行润樱,直到遇到下一個yield (yield_02),
并將這個yield (yield_02)的右邊的值返回給調(diào)用者,生成器件停在yield (yield_02),程序跳動回調(diào)用者執(zhí)行
如果是最后一次調(diào)用
也就是及接下來沒有代碼或者剩下的所有代碼中沒有yield(全部執(zhí)行完也不會遇到y(tǒng)ield),執(zhí)行完后直接向調(diào)用者拋出StopIteration(如果生成器最有有return XX,則我們將XX包在StopIteration對象中返回給調(diào)用者)
'''
01-從生成器預(yù)激到send,yield交互流程
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門舶胀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來概说,“玉大人,你說我怎么就攤上這事嚣伐√桥猓” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵轩端,是天一觀的道長放典。 經(jīng)常有香客問我,道長基茵,這世上最難降的妖魔是什么奋构? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮拱层,結(jié)果婚禮上弥臼,老公的妹妹穿的比我還像新娘。我一直安慰自己舱呻,他們只是感情好醋火,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱吕,像睡著了一般芥驳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茬高,一...
- 文/蒼蘭香墨 我猛地睜開眼谬以,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了由桌?” 一聲冷哼從身側(cè)響起为黎,我...
- 正文 年R本政府宣布洞难,位于F島的核電站,受9級特大地震影響揭朝,放射性物質(zhì)發(fā)生泄漏队贱。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一潭袱、第九天 我趴在偏房一處隱蔽的房頂上張望柱嫌。 院中可真熱鬧,春花似錦屯换、人聲如沸编丘。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽嘉抓。三九已至,卻和暖如春晕窑,著一層夾襖步出監(jiān)牢的瞬間抑片,已是汗流浹背。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- 帶有yield的函數(shù)即變?yōu)樯善餮媸啵枰米兞縼斫邮芏迹祷豨enertor對象,next()方法 和__next__...
- 上一篇文章為:→1.1.3__slots__ 生成器 1. 什么是生成器 通過列表生成式,我們可以直接創(chuàng)建一個列表...
- 本片筆記學(xué)習(xí)自:Improve Your Python: 'yield' and Generators Expla...
- 每天的開始都是渾渾噩噩中被鬧鐘叫醒戳鹅,匆匆忙忙趕上出門防止遲到而扣除本就微薄的工資,穿行在車水馬龍的早高峰昏兆,咬一口路...