Python Yield 精髓

對(duì) Python 中的 Yield 一直理解的不夠深刻娄昆,甚至存在誤解。遇到一個(gè)神奇的用法后(多個(gè) yield 連續(xù)使用)又好好研究了下,以下記錄鄙人粗糙見(jiàn)解。

首先簡(jiǎn)單科普一下 yield:

要理解 yield 語(yǔ)句盒延,關(guān)鍵要理解 python 的生成器。 用官網(wǎng)的說(shuō)法1鼠冕、2兰英, 生成器就是一個(gè)返回迭代器(iterator)的函數(shù)。 和普通函數(shù)唯一的區(qū)別就是這個(gè)函數(shù)包含 yield 語(yǔ)句供鸠。
包含了 yield 的函數(shù),就是一個(gè)生成器

我是在學(xué)爬蟲(chóng) scrapy 框架時(shí)遇見(jiàn)多個(gè)yield 連續(xù)使用
在最后兩行代碼:

# 例1
def parse(self, response):
        # 1取出符合條件的  tr列表
        tr_list = response.xpath('//tr[@class="even"] | //tr[@class="odd"]')

        # 判斷數(shù)據(jù)的有無(wú) ,沒(méi)有 到底了
        if not tr_list:
            return

        # 2.遍歷 每一個(gè) tr 取出內(nèi)容
        for tr in tr_list:
            item = TencentItem()
            item['work_name'] = tr.xpath('./td[1]/a/text()').extract_first()
            item['work_type'] = tr.xpath('./td[2]/text()').extract_first()
            item['work_count'] = tr.xpath('./td[3]/text()').extract_first()
            item['work_place'] = tr.xpath('./td[4]/text()').extract_first()
            item['work_time'] = tr.xpath('./td[5]/text()').extract_first()
            item['work_link'] = 'https://hr.tencent.com/' + tr.xpath('./td[1]/a/@href').extract_first()

            # 給 引擎 -->管道
            yield item

            # 告訴 引擎  請(qǐng)求詳情頁(yè)
            yield scrapy.Request(url=item['work_link'], callback=self.detail_parse)

初次看到時(shí)陨闹,對(duì)于以上代碼執(zhí)行機(jī)制實(shí)在難以理解楞捂!
因?yàn)樵谧畛醯睦斫饫铮?yield 有兩個(gè)作用:

  • 暫停執(zhí)行當(dāng)前代碼,并記錄當(dāng)前位置
  • 相當(dāng)于 return趋厉, 可以在后面返回值

繼續(xù)執(zhí)行 yield 下面的代碼需要使用 next() 或者 send()寨闹。
我就困惑了, 這里兩個(gè) yield 之間沒(méi)有使用 next() 或者 send() 方法呀君账,那么它是怎么執(zhí)行的呢繁堡?
然后我自己寫(xiě)了一個(gè)簡(jiǎn)單的測(cè)試函數(shù),來(lái)探究 yield 的執(zhí)行機(jī)制:

# 例2
# 自定義一個(gè)生成器
def genter():
    a = 4
    b = 5
    c = 6
    for i in range(5):
        yield a
        print('hhh'+str(i))
        yield b
        print("aaa" + str(i))
        yield c

# 包含了yield 的 genter() 就是一個(gè)生成器
res = genter()
for i, c in enumerate(res):
    if i > 1:
        # 通過(guò) break 來(lái)測(cè)試執(zhí)行的結(jié)果
        break
    print(c)

而其結(jié)果是:

4
hhh0
5
aaa0

大家應(yīng)該知道:

在取值時(shí)乡数,使用 for 語(yǔ)句椭蹄,里面封裝了 next 方法。來(lái)一個(gè)個(gè)取出生成器的值净赴,由程序運(yùn)行結(jié)果可知:例2 中 genter() 實(shí)際是通過(guò) 多個(gè) yield 實(shí)現(xiàn)了包含多個(gè)值的生成器
顛覆認(rèn)知的是:yield 并沒(méi)有暫停绳矩,yield 語(yǔ)句后面的 print 正常打印了!玖翅!
因此與其說(shuō) yield 的作用是暫停并記錄位置翼馆, 不如嚴(yán)謹(jǐn)?shù)卣f(shuō)成:只有在只有一個(gè)yield 的情況下割以, 才是暫停并記錄位置。函數(shù)的反復(fù)調(diào)用应媚,也是這個(gè)值(迭代器)的反復(fù)調(diào)用严沥;而上述yield 之間的 next 方法就通過(guò) for 循環(huán)調(diào)用了
多個(gè) yield 的情況下,應(yīng)該理解成:這個(gè)函數(shù)本身就是一個(gè)擁有多個(gè)值(迭代器)的迭代器中姜,此時(shí) yield 的暫停消玄, 應(yīng)該暫停于下一個(gè) yield 之前!

一般我們所見(jiàn)到的生成器扎筒,只有一個(gè) yield莱找,通過(guò)反復(fù)調(diào)用這個(gè)方法,來(lái)實(shí)現(xiàn)所謂的生成器嗜桌。在這樣的情況下奥溺,我們也習(xí)慣地以為 yield 的兩個(gè)作用之一就是暫停執(zhí)行當(dāng)前的代碼, 并記錄當(dāng)前位置骨宠,并且有 return 的作用浮定。

不過(guò)多個(gè) yield 和單個(gè) yield 的情況,為何會(huì)不一樣呢层亿?
其底層的原理應(yīng)該一樣才對(duì)桦卒!

對(duì)于這個(gè),啃了下官方文檔匿又,沒(méi)看太明白方灾。可能要去學(xué)了 C 語(yǔ)言才能理解÷蹈現(xiàn)在粗淺理解:之所以包含了 yield 關(guān)鍵字的函數(shù)就是一個(gè)生成器裕偿, 是因?yàn)?yield自身就是生成器

那么對(duì)于例1 中的情況就很好理解了痛单,parse 本身是一個(gè)生成器嘿棘,scrapy 引擎會(huì)在調(diào)用其中值時(shí)添加next() 方法吧~
另外,除了官方文檔旭绒, 還可以看下這篇講協(xié)程的文檔鸟妙。

由于學(xué)藝未精,如有錯(cuò)誤挥吵,望不吝賜教重父,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末忽匈,一起剝皮案震驚了整個(gè)濱河市坪郭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脉幢,老刑警劉巖歪沃,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗦锐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡沪曙,警方通過(guò)查閱死者的電腦和手機(jī)奕污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)液走,“玉大人碳默,你說(shuō)我怎么就攤上這事徐绑》杼叮” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵懒棉,是天一觀(guān)的道長(zhǎng)巷懈。 經(jīng)常有香客問(wèn)我该抒,道長(zhǎng),這世上最難降的妖魔是什么顶燕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任凑保,我火速辦了婚禮,結(jié)果婚禮上涌攻,老公的妹妹穿的比我還像新娘欧引。我一直安慰自己,他們只是感情好恳谎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布芝此。 她就那樣靜靜地躺著,像睡著了一般因痛。 火紅的嫁衣襯著肌膚如雪癌蓖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天婚肆,我揣著相機(jī)與錄音,去河邊找鬼坐慰。 笑死较性,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的结胀。 我是一名探鬼主播赞咙,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼糟港!你這毒婦竟也來(lái)了攀操?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤秸抚,失蹤者是張志新(化名)和其女友劉穎速和,沒(méi)想到半個(gè)月后歹垫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颠放,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年排惨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碰凶。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡暮芭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欲低,到底是詐尸還是另有隱情辕宏,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布砾莱,位于F島的核電站瑞筐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏恤磷。R本人自食惡果不足惜面哼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扫步。 院中可真熱鬧魔策,春花似錦、人聲如沸河胎。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)游岳。三九已至政敢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胚迫,已是汗流浹背喷户。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留访锻,地道東北人褪尝。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像期犬,于是被迫代替她去往敵國(guó)和親河哑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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

  • 你不知道JS:異步 第四章:生成器(Generators) 在第二章龟虎,我們明確了采用回調(diào)表示異步流的兩個(gè)關(guān)鍵缺點(diǎn):...
    purple_force閱讀 960評(píng)論 0 2
  • 你不知道JS:異步 第四章:生成器(Generators) 接上篇4-1 生成器委托(Generator Dele...
    purple_force閱讀 504評(píng)論 0 1
  • 簡(jiǎn)介 基本概念 Generator函數(shù)是ES6提供的一種異步編程解決方案璃谨,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同。本章詳細(xì)介紹...
    呼呼哥閱讀 1,075評(píng)論 0 4
  • 本文作者就是我,簡(jiǎn)書(shū)的microkof佳吞。如果您覺(jué)得本文對(duì)您的工作有意義拱雏,產(chǎn)生了不可估量的價(jià)值,那么請(qǐng)您不吝打賞我容达,...
    microkof閱讀 23,732評(píng)論 16 78
  • 讀方浚頤(1815-1888)《二知軒文存》古涧,三十四卷,光緒四年刻本花盐。 1.守變——二知軒文存羡滑,卷一,第35頁(yè)算芯。 ...
    淺智閱讀 1,121評(píng)論 2 0