日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python: generator, yield, yield from 详解

發(fā)布時間:2025/6/17 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python: generator, yield, yield from 详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.Generator Expressions

生成器表達式是用小括號表示的簡單生成器標記法:

generator_expression ::= "(" expression comp_for ")"

生成器表達式產生一個生成器對象,它的語法和for類似,出了它是被“()”包含,而不是[]或{};

生成器表達式中變量的計算被延遲到__next__()函數的調用,然而最左邊for循環(huán)子句被立即計算,這樣,如果他有錯誤的話可以被立即看到。后面的for循環(huán)子句不能被立即計算,因為他們可能依賴于前面的for循環(huán),例如(x*y?for?x?in?range(10)?for?y?in?bar(x)

python3.6以后,如果生成器出現在async?def function中,那么async for子句和await表達式可以被理解為是異步的。如果生成器表達式包含async for子句或者await表達式,就叫做異步生成器表達式。異步生成器表達式產生一個新的異步生成器對象,它是一個異步迭代器。

?

2. Yield Expressions

yield_atom ::= "(" yield_expression ")" yield_expression ::= "yield" [expression_list | "from" expression]

Yield表達式用于定義一個生成器函數或異步生成器函數,因此只能被用于一個函數定義體內。在一個函數定義體中使用yield表達式使其成為生成器,
在一個async def函數體內使用yield表達式使協程函數成為一個異步生成器。例如:
def gen(): //定義一個生成器函數
  yield 123
async def agen(): //定義一個異步生成器函數
  yield 123

當一個生成器函數被調用,它返回一個迭代器,也叫生成器。這個生成器控制生成器函數的執(zhí)行。當生成器的一個函數被調用的時候,生成器函數開始執(zhí)行。
執(zhí)行到第一個yield表達式時,掛起,返回expression_list的值給調用者。對于掛起,我們指的是所有局部狀態(tài)被保留,包含當前局部變量的綁定,
指令指針,內部調用棧,任何異常處理狀態(tài)。當通過調用生成器的一個函數恢復執(zhí)行時,函數的執(zhí)行就好像是從外部再次調用yield表達式一樣。恢復執(zhí)行后,
yield表達式的值取決調用的方法。如果是__next__()被調用(一般通過for循環(huán)或者內置的next()函數),那么值是None。如果是send()被調用,
值是傳給send的參數的值。

所有的這些使得生成器函數非常像協程;它產生多次值,有多個入口點并且執(zhí)行可以被掛起。唯一的不同是,生成器函數yield后不能控制程序從哪里繼續(xù)執(zhí)行,
控制權總是傳回給生成器的調用者。

yield表達式可以在try塊的任何地方,如果生成器在被結束(到達零引用或者因為垃圾回收機制)之前沒有被恢復執(zhí)行,生成器的close函數被調用,因此finally
子句被執(zhí)行。
當yield from <expr> 被使用,它把附加的表達式當成一個子迭代器,所有子迭代器產生的值被直接傳回給當前生成器函數的調用者。當前生成器調用send的參數值
和調用throw的異常參數 都將被傳給底層迭代器(子迭代器),如果他有對應的方法的話。否則,send導致AttributeError或者TypeError,而throw立即
raise傳給他的異常。
當底層迭代器執(zhí)行完成,StopIteration對象的value值變成這個yield from表達式的值。這個值可以被顯式的設置當產生StopIteration時,或者自動設置,如果
子迭代器是一個生成器(子生成器返回一個值) 3. 生成器-迭代器 方法
這部分介紹生成器迭代器的方法,他們可以被用來控制生成器函數的執(zhí)行。當生成器正在執(zhí)行時調用這些函數將導致ValueError。
(1)generator.__next__()
開始生成器函數的執(zhí)行或者從最后被執(zhí)行的yield表達式中恢復執(zhí)行,如果是恢復執(zhí)行,yield表達式的值是None,繼續(xù)執(zhí)行到下一個yield表達式,
掛起,返回expression_list的值給__next__()的調用者。如果生成器沒有再yield一個值,則產生一個StopIteration異常
這個方法一般被隱式調用,例如for循環(huán),next()
(2)generator.send(value)
恢復執(zhí)行并且發(fā)送一個值到生成器函數。這個value參數就是當前yield表達式的結果。send方法返回下一個生成器yield的值
如果沒有yield,返回StopIteration。當用send來啟動生成器,他的參數必須是None,因為沒有yield表達式接收值。
(3)generator.throw(type[,value[,traceback]])
在生成器掛起的地方產生一個type類型的異常,并且返回下一個生成器函數yield的值,如果沒有yield,返回StopIteration。
如果生成器函數沒有捕獲這個傳進去的異常 ,或者產生了另一個不同的異常,那么將這個異常傳遞給調用者。
(4)generator.close()
在生成器掛起的地方產生一個GeneratorExit(),如果生成器之后優(yōu)雅的退出,已經關閉,或者產生了一個GeneartorExit(不捕獲該異常),close將返回到它的
調用者。如果生成器yield一個值,那么產生一個RuntimeError。如果生成器產生了任何其他異常,將傳遞給調用者。如果
生成器因為一個異常或者正常退出,那么close不做任何事情。
實例: >>> def echo(value=None): ... print("Execution starts when 'next()' is called for the first time.") ... try: ... while True: ... try: ... value = (yield value) ... except Exception as e: ... value = e ... finally: ... print("Don't forget to clean up when 'close()' is called.") ... >>> generator = echo(1) >>> print(next(generator)) Execution starts when 'next()' is called for the first time. 1 >>> print(next(generator)) None >>> print(generator.send(2)) 2 >>> generator.throw(TypeError, "spam") TypeError('spam',) >>> generator.close() Don't forget to clean up when 'close()' is called.

PEP380 加入了yield from表達式,允許一個生成器委派部分操作給另一個生成器。這可以剔除一部分包含yield的代碼放到另一個生成器。另外,
子生成器可以返回一個值,這個值對于委托生成器也是可用的。
雖然主要涉及用來委派一個子生成器,但是yield from 表達式事實上可以委派任何的子迭代器。
低于簡單的迭代器, yield from iterable 本質上就是一個簡短的形式:for item in iterable: yield item,例如:
>>> def g(x): ... yield from range(x, 0, -1) ... yield from range(x) ... >>> list(g(5)) [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
然而,不像普通的循環(huán),yield from 允許子生成器直接從調用區(qū)域接收send和throw的值,并且返回一個最后的值給外層生成器。示例如下: >>> def accumulate(): ... tally = 0 ... while 1: ... next = yield ... if next is None: ... return tally ... tally += next ... >>> def gather_tallies(tallies): ... while 1: ... tally = yield from accumulate() ... tallies.append(tally) ... >>> tallies = [] >>> acc = gather_tallies(tallies) >>> next(acc) # Ensure the accumulator is ready to accept values >>> for i in range(4): ... acc.send(i) ... >>> acc.send(None) # Finish the first tally >>> for i in range(5): ... acc.send(i) ... >>> acc.send(None) # Finish the second tally >>> tallies [6, 10] ?



?

轉載于:https://www.cnblogs.com/programmer-wfq/p/7173580.html

總結

以上是生活随笔為你收集整理的Python: generator, yield, yield from 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲成人资源 | 国产又大又黄视频 | 成人看片网| 思思99精品视频在线观看 | 精品盗摄一区二区三区 | 五月天综合 | 青娱网电信一区电信二区电信三区 | 成人一区二区三区四区 | 精品久久人妻av中文字幕 | 91色偷偷 | 亚洲制服另类 | 欧美成人久久久免费播放 | 又欲又污又肉又黄短文 | 在线视频h| 国产主播av在线 | 亚洲天堂视频在线播放 | 欧美性成人 | 午夜影院在线 | 国产精品无码免费专区午夜 | av一区二区三区四区 | 国产精品免费一区二区三区 | 西西4444www大胆无视频 | 亚洲做受高潮无遮挡 | 亚洲精品久久久久国产 | 免费毛片网站在线观看 | 国产真人无码作爱视频免费 | 中文日韩字幕 | 好吊色这里只有精品 | 少女情窦初开的第4集在线观看 | www色中色| 免费黄色看片 | 色婷婷777777仙踪林 | 国产女教师一区二区三区 | 91精品国自产 | 日韩二区在线 | 国产美女免费无遮挡 | 成人小视频在线观看 | 91精品视频一区二区三区 | 神马久久午夜 | 久草资源在线视频 | 久久五| 免费av不卡在线观看 | 亚洲视频高清 | 免费一级特黄毛大片 | 另类国产 | 丁香花在线影院观看在线播放 | 成人高清| 天天色天天 | 国产男女啪啪 | 亚洲欧洲国产综合 | 91精品欧美一区二区三区 | 欧美一区二区在线视频观看 | 亚洲www啪成人一区二区麻豆 | 男女免费看 | 午夜视频免费观看 | 好吊色这里只有精品 | 午夜dv内射一区二区 | 狠狠久久| 免费观看视频一区 | 一区二区自拍偷拍 | 欧美日韩中出 | 亚洲av无码乱码国产精品久久 | 国色天香网站 | 永久免费看mv网站入口亚洲 | 欧美性猛交7777777 | 久一在线 | 九一精品在线 | 天天插天天透 | av动漫免费看 | 扒开腿揉捏花蒂h | 黄色一级片免费在线观看 | 国产高潮久久 | 男女污污软件 | av第一区 | 国产性猛交╳xxx乱大交 | 日本黄色录象 | 女人脱下裤子让男人捅 | 风流少妇一区二区三区91 | 99热精品久久 | 韩国一区二区三区在线观看 | 日本一区二区色 | 五月婷婷在线观看视频 | 亚洲精品美女久久久 | 青青草一区二区三区 | 欧美极品少妇xxxxⅹ裸体艺术 | 欧美a一级 | www.com欧美 | 人妻精油按摩bd高清中文字幕 | av福利片| 午夜人体视频 | 国产精彩视频一区 | 九九热最新网址 | 侵犯亲女在线播放视频 | 日韩亚洲欧美一区二区三区 | 黄色国产免费 | 在线免费福利视频 | 涩涩视频在线观看免费 | av资源网址| 国产精品免费视频一区二区 |