01-從生成器預(yù)激到send,yield交互流程


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)用者)
'''

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羡棵,一起剝皮案震驚了整個濱河市壹若,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌皂冰,老刑警劉巖店展,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秃流,居然都是意外死亡赂蕴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門舶胀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來概说,“玉大人,你說我怎么就攤上這事嚣伐√桥猓” “怎么了?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵轩端,是天一觀的道長放典。 經(jīng)常有香客問我,道長基茵,這世上最難降的妖魔是什么奋构? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮拱层,結(jié)果婚禮上弥臼,老公的妹妹穿的比我還像新娘。我一直安慰自己舱呻,他們只是感情好醋火,可當(dāng)我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱吕,像睡著了一般芥驳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茬高,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天兆旬,我揣著相機與錄音,去河邊找鬼怎栽。 笑死丽猬,一個胖子當(dāng)著我的面吹牛宿饱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脚祟,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼谬以,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了由桌?” 一聲冷哼從身側(cè)響起为黎,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎行您,沒想到半個月后铭乾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡娃循,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年炕檩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捌斧。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡笛质,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出骤星,到底是詐尸還是另有隱情经瓷,我是刑警寧澤爆哑,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布洞难,位于F島的核電站,受9級特大地震影響揭朝,放射性物質(zhì)發(fā)生泄漏队贱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一潭袱、第九天 我趴在偏房一處隱蔽的房頂上張望柱嫌。 院中可真熱鬧,春花似錦屯换、人聲如沸编丘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘉抓。三九已至,卻和暖如春晕窑,著一層夾襖步出監(jiān)牢的瞬間抑片,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工杨赤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留敞斋,地道東北人截汪。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像植捎,于是被迫代替她去往敵國和親衙解。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,576評論 2 349

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