摘要:我們可以看一下的可見是由內(nèi)部支持的,其實現(xiàn)原理上就避免了棧進棧出的消耗,直接由最內(nèi)層的返回值。另外可以實現(xiàn)外部直接向最內(nèi)層的傳遞值,比如這段代碼的輸出是這樣傳值的方式,在用循環(huán)重新的模式下是無法實現(xiàn)的。這也就是必須使用,而不能使用的原因。
在python 3.3里,generator新增了一個語法 yield from
這個yield from的作用是什么?看下面兩段對比的代碼:
def zero_to_nine(): for i in range(10): yield i def wrap_generator(): for i in zero_to_nine(): yield i print(list(zero_to_nine())) print(list(wrap_generator()))
可以看到一個問題,如果一個函數(shù)內(nèi)部調(diào)用了一個generator,它自身如果還希望是以generator的形式返回值的話,就需要用for循環(huán)重新yield一次。
使用yield from可以簡化這個委托給子generator的過程
def zero_to_nine(): for i in range(10): yield i def wrap_generator(): yield from zero_to_nine() print(list(zero_to_nine())) print(list(wrap_generator()))
如果只是這么一點寫法上的區(qū)別的話,也就不勞煩BDFL添加新的語法了。我們可以看一下wrap_generator的bytecode
0 LOAD_GLOBAL 0 (zero_to_nine) 3 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 6 GET_ITER 7 LOAD_CONST 0 (None) 10 YIELD_FROM 11 POP_TOP 12 LOAD_CONST 0 (None) 15 RETURN_VALUE
可見YIELD FROM是由cPython內(nèi)部支持的,其實現(xiàn)原理上就避免了棧進棧出的消耗,直接由最內(nèi)層的frame返回(yield)值。
另外YIELD FROM可以實現(xiàn)外部直接向最內(nèi)層的generator傳遞值,比如
def i_yield_whatever_input_is(): input = None while True: input = yield input def wrap_generator(): yield from i_yield_whatever_input_is() gen = wrap_generator() print(gen.send(None)) print(gen.send(1)) print(gen.send(2)) print(gen.send(3))
這段代碼的輸出是
None 1 2 3
這樣send傳值的方式,在用for循環(huán)重新yield的模式下是無法實現(xiàn)的。這也就是tulip必須使用yield from,而不能使用yield的原因。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/37396.html
摘要:比如里可以直接把執(zhí)行權(quán)交給,而完全不知情。雖然不能和多線程相比,但是效果是類似的。對于多線程的代碼,是任何一行代碼都可能與其他線程并行。加上協(xié)程之間有共享狀態(tài)的話,一定程度上會產(chǎn)生類似多線程的并發(fā)讀寫狀態(tài)的。 前面講generator是顯式的協(xié)程的時候缺一個例子,現(xiàn)在補上 def parent_generator(): print(hello) yield from ...
摘要:從到到再到,各家的語法都不太一樣。底層的實現(xiàn)是,看名字應(yīng)該是的意思。然后在這個基礎(chǔ)上實現(xiàn)了的和的。的的語法風格也是類似所以從語法上來說就三類這樣強制要求的為代表的隱式控制權(quán)的為代表強買強賣編碼風格的 從generator到greenlet到stackless再到pypy,各家的語法都不太一樣。pypy底層的實現(xiàn)是continulet,看名字應(yīng)該是continuation的意思。然后在這...
摘要:的是可以有輸入輸出的,這個特性并不廣為人知。也就是要求不返回值,而是拋出給定的異常。執(zhí)行之后的輸出與前面是一樣的。 Python的generator是可以有輸入輸出的,這個特性并不廣為人知。這其實是一個挺有用的特性,利用其外部可控制執(zhí)行進度的特性,再加上可以與外部進行輸入輸出,generator可以被用來打造成一個異步執(zhí)行框架,或者說是協(xié)程調(diào)度引擎。 我們先來看一個最簡單的例子,gen...
摘要:協(xié)程其實就是一個可中途中斷,由外部來控制執(zhí)行進程的函數(shù)。這些第三方的選擇的共同特點是協(xié)程的都是隱式的。這就是顯示控制和隱式控制的區(qū)別。本文討論的協(xié)程就是這一種,后面會逐漸展開到如何利用這種顯示控制的協(xié)程來解決阻塞和流程阻塞的問題。 Python官方的實現(xiàn)里,協(xié)程只有g(shù)enerator這一招。協(xié)程其實就是一個可中途中斷,由外部來控制執(zhí)行進程的函數(shù)。除了官方的generator,還有很多第...
摘要:生成器用于定義生成器函數(shù)只要存在該函數(shù)必定是一個生成器調(diào)用該函數(shù)返回一個生成器讓一個生成器前進使用使一個生成器前進到下一個語句處,并將產(chǎn)出值作為其返回值。 前言 這篇文章大部分來自 David Beazley 在 PyCon 2014 的 PPT 《Generators: The Final Frontier》。這個PPT很長而且非常燒腦,建議在閱讀前應(yīng)了解 Python 的生成器與攜...
閱讀 3094·2021-08-03 14:05
閱讀 2140·2019-08-29 15:35
閱讀 678·2019-08-29 13:30
閱讀 3169·2019-08-29 13:20
閱讀 2531·2019-08-23 18:15
閱讀 1797·2019-08-23 14:57
閱讀 2213·2019-08-23 13:57
閱讀 1310·2019-08-23 12:10