摘要:第二次迭代時(shí),使用,那么,就是強(qiáng)行修改表達(dá)式的值為,本來(lái)是的,那么與都有返回值,它們的返回值是當(dāng)前迭代遇到時(shí),后面表達(dá)式的值,其實(shí)就是當(dāng)前迭代中后面的參數(shù)。
yield
為了精通 yield ,你必須要理解:當(dāng)你調(diào)用這個(gè)函數(shù)的時(shí)候,函數(shù)內(nèi)部的代碼并不立馬執(zhí)行 ,這個(gè)函數(shù)只是返回一個(gè)生成器對(duì)象,這有點(diǎn)蹊蹺不是嗎。
那么,函數(shù)內(nèi)的代碼什么時(shí)候執(zhí)行呢?當(dāng)你使用for進(jìn)行迭代的時(shí)候.
現(xiàn)在到了關(guān)鍵點(diǎn)了!
第一次迭代中你的函數(shù)會(huì)執(zhí)行,從開(kāi)始到達(dá) yield 關(guān)鍵字,然后返回 yield 后的值作為第一次迭代的返回值. 然后,每次執(zhí)行這個(gè)函數(shù)都會(huì)繼續(xù)執(zhí)行你在函數(shù)內(nèi)部定義的那個(gè)循環(huán)的下一次,再返回那個(gè)值,直到?jīng)]有可以返回的。
1、通常的for...in...循環(huán)中,in后面是一個(gè)數(shù)組,這個(gè)數(shù)組就是一個(gè)可迭代對(duì)象,類似的還有鏈表,字符串,文件。它可以是mylist = [1, 2, 3],也可以是mylist = [x*x for x in range(3)]。
它的缺陷是所有數(shù)據(jù)都在內(nèi)存中,如果有海量數(shù)據(jù)的話將會(huì)非常耗內(nèi)存。
2、生成器是可以迭代的,但只可以讀取它一次。因?yàn)橛玫臅r(shí)候才生成。比如 mygenerator = (x*x for x in range(3)),注意這里用到了(),它就不是數(shù)組,而上面的例子是[]。
3、我理解的生成器(generator)能夠迭代的關(guān)鍵是它有一個(gè)next()方法,工作原理就是通過(guò)重復(fù)調(diào)用next()方法,直到捕獲一個(gè)異常。
4、帶有 yield 的函數(shù)不再是一個(gè)普通函數(shù),而是一個(gè)生成器generator,可用于迭代,工作原理同上。
5、yield 是一個(gè)類似 return 的關(guān)鍵字,迭代一次遇到y(tǒng)ield時(shí)就返回yield后面(右邊)的值。重點(diǎn)是:下一次迭代時(shí),從上一次迭代遇到的yield后面的代碼(下一行)開(kāi)始執(zhí)行。
6、簡(jiǎn)要理解:yield就是 return 返回一個(gè)值,并且記住這個(gè)返回的位置,下次迭代就從這個(gè)位置后(下一行)開(kāi)始。
7、帶有yield的函數(shù)不僅僅只用于for循環(huán)中,而且可用于某個(gè)函數(shù)的參數(shù),只要這個(gè)函數(shù)的參數(shù)允許迭代參數(shù)。比如array.extend函數(shù),它的原型是array.extend(iterable)。
8、send(msg)與next()的區(qū)別在于send可以傳遞參數(shù)給yield表達(dá)式,這時(shí)傳遞的參數(shù)會(huì)作為yield表達(dá)式的值,而yield的參數(shù)是返回給調(diào)用者的值。——換句話說(shuō),就是send可以強(qiáng)行修改上一個(gè)yield表達(dá)式值。比如函數(shù)中有一個(gè)yield賦值,a = yield 5,第一次迭代到這里會(huì)返回5,a還沒(méi)有賦值。第二次迭代時(shí),使用.send(10),那么,就是強(qiáng)行修改yield 5表達(dá)式的值為10,本來(lái)是5的,那么a=10
9、send(msg)與next()都有返回值,它們的返回值是當(dāng)前迭代遇到y(tǒng)ield時(shí),yield后面表達(dá)式的值,其實(shí)就是當(dāng)前迭代中yield后面的參數(shù)。
10、第一次調(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)。
代碼示例1:
#encoding:UTF-8 def yield_test(n): for i in range(n): yield call(i) print("i=",i) #做一些其它的事情 print("do something.") print("end.") def call(i): return i*2 #使用for循環(huán) for i in yield_test(5): print(i,",")
結(jié)果是:
yield from0 ,
i= 0
2 ,
i= 1
4 ,
i= 2
6 ,
i= 3
8 ,
i= 4
do something.
end.理解的關(guān)鍵在于:下次迭代時(shí),代碼從yield的下一跳語(yǔ)句開(kāi)始執(zhí)行。
python yield from 語(yǔ)法
yield from 是 Python3.3 后新加的語(yǔ)言結(jié)構(gòu)。和其他語(yǔ)言的await關(guān)鍵字類似,它表示:*在生成器 gen 中使用 yield from subgen()時(shí),subgen 會(huì)獲得控制權(quán),把產(chǎn)出的值傳個(gè)gen的調(diào)用方,即調(diào)用方可以直接控制subgen。于此同時(shí),gen會(huì)阻塞,等待subgen終止。yield語(yǔ)法比較簡(jiǎn)單, 教程也很多 , yield from的中文講解很少 , python官網(wǎng)是這樣解釋的
PEP 380 adds the yield from expression, allowing a generator to delegate part of its operations to another generator. This allows a section of code containing yield to be factored out and placed in another generator. Additionally, the subgenerator is allowed to return with a value, and the value is made available to the delegating generator.
官網(wǎng)鏈接
大意是說(shuō) yield from 表達(dá)式允許一個(gè)生成器代理另一個(gè)生成器, 這樣就允許生成器被替換為另一個(gè)生成器, 子生成器允許返回值
def g1(x): yield range(x) def g2(x): yield from range(x) it1 = g1(5) it2 = g2(5) #it1[0] = range(0,5) #it2 = range(0,5) print( [ x for x in it1] ) #out [range(0, 5)] print( [ x for x in it2] ) #out [0, 1, 2, 3, 4]
可以看到 , yield返回一個(gè)生成器 , 這個(gè)生成器就是range自身 , yield from 也返回一個(gè)生成器, 這個(gè)生成器是由range代理的
yield from 在遞歸結(jié)構(gòu)中常用 , 例如
class Node: def __init__(self, value): self._value = value self._children = [] def __repr__(self): return "Node({!r})".format(self._value) def add_child(self, node): self._children.append(node) def __iter__(self): return iter(self._children) def depth_first(self): yield self for c in self: yield from c.depth_first()
如果不加上from , depth_first 只能返回根節(jié)點(diǎn)的值
yield from 詳細(xì)解釋http://blog.gusibi.com/post/p...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/41053.html
摘要:在種,使用關(guān)鍵字定義的迭代器也被稱為生成器迭代器迭代器是訪問(wèn)集合內(nèi)元素的一種方式。調(diào)用任何定義包含關(guān)鍵字的函數(shù)都不會(huì)執(zhí)行該函數(shù),而是會(huì)獲得一個(gè)隊(duì)?wèi)?yīng)于該函數(shù)的迭代器。 上一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第一節(jié):同步與異步I/O下一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第三節(jié):協(xié)程 協(xié)程是Tornado中進(jìn)行異步I/O代碼開(kāi)發(fā)的方法...
摘要:與子生成器是開(kāi)始引入的新特性。我們把這種一個(gè)生成器中調(diào)用的另一個(gè)生成器叫做子生成器,而這個(gè)子生成器由關(guān)鍵字生成。由于子生成器很常用,所以引入了新的語(yǔ)法來(lái)簡(jiǎn)化這個(gè)代碼。下次,會(huì)繼續(xù)對(duì)之前的結(jié)果進(jìn)行乘方,直到結(jié)果超過(guò)為止。 Python高級(jí)語(yǔ)法中,由一個(gè)yield關(guān)鍵詞生成的generator生成器,是精髓中的精髓。它雖然比裝飾器、魔法方法更難懂,但是它強(qiáng)大到我們難以想象的地步:小到簡(jiǎn)單的...
摘要:是的一個(gè)關(guān)鍵字,剛接觸的時(shí)候?qū)@個(gè)關(guān)鍵字一知半解,掌握之后才發(fā)現(xiàn)這關(guān)鍵字有大用,本文將對(duì)的使用方法好好梳理一番。使用創(chuàng)建生成器在中,生成器是一種可迭代對(duì)象,但可迭代對(duì)象不一定是生成器。 yield是python的一個(gè)關(guān)鍵字,剛接觸python的時(shí)候?qū)@個(gè)關(guān)鍵字一知半解,掌握之后才發(fā)現(xiàn)這關(guān)鍵字有大用,本文將對(duì)yield的使用方法好好梳理一番。 1 使用yield創(chuàng)建生成器 在python...
摘要:于此同時(shí),會(huì)阻塞,等待終止。子生成器返回之后,解釋器會(huì)拋出異常,并把返回值附加到異常對(duì)象上,只是委派生成器恢復(fù)。實(shí)例運(yùn)行完畢后,返回的值綁定到上。這一部分處理調(diào)用方通過(guò)方法傳入的異常。之外的異常會(huì)向上冒泡。 上一篇python協(xié)程1:yield的使用介紹了: 生成器作為協(xié)程使用時(shí)的行為和狀態(tài) 使用裝飾器預(yù)激協(xié)程 調(diào)用方如何使用生成器對(duì)象的 .throw(...) 和 .close()...
閱讀 4963·2021-11-18 13:23
閱讀 963·2021-09-22 15:24
閱讀 2000·2021-09-06 15:00
閱讀 2696·2021-09-03 10:30
閱讀 1348·2021-09-02 15:15
閱讀 2152·2019-08-30 15:54
閱讀 3094·2019-08-30 15:44
閱讀 1519·2019-08-29 15:12