国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python 3中的yield from語法詳解

Python 3中的yield from語法詳解

2020-09-18 10:32Kay Zheng Python

在python 3.3里,generator新增了一個語法 yield from,這個yield from的作用是什么?語法是什么呢?下面通過這篇文章主要給大家詳細介紹了Python 3中yield from語法的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

最近在搗鼓Autobahn,它有給出個例子是基于asyncio 的,想著說放到pypy3上跑跑看竟然就……失敗了。 pip install asyncio直接報invalid syntax,粗看還以為2to3處理的時 候有問題——這不能怪我,好~多package都是用2寫了然后轉成3的——結果發 現asyncio本來就只支持3.3+的版本,才又回頭看代碼,赫然發現一句 yield from;yield我知道,但是yield from是神馬?

PEP-380

好吧這個標題是我google出來的,yield from的前世今生都在 這個PEP里面,總之大意是原本的yield語句只能將CPU控制權 還給直接調用者,當你想要將一個generator或者coroutine里帶有 yield語句的邏輯重構到另一個generator(原文是subgenerator) 里的時候,會非常麻煩,因為外面的generator要負責為里面的 generator做消息傳遞;所以某人有個想法是讓python把消息傳遞 封裝起來,使其對程序猿透明,于是就有了yield from。

PEP-380規定了yield from的語義,或者說嵌套的generator應該 有的行為模式。

假設A函數中有這樣一個語句

?
1
yield from B()

B()返回的是一個可迭代(iterable)的對象b,那么A()會返回一個 generator——照我們的命名規范,名字叫a——那么:

  1. b迭代產生的每個值都直接傳遞給a的調用者。
  2. 所有通過send方法發送到a的值都被直接傳遞給b. 如果發送的 值是None,則調用b的__next__()方法,否則調用b的send 方法。如果對b的方法調用產生StopIteration異常,a會繼續 執行yield from后面的語句,而其他異常則會傳播到a中,導 致a在執行yield from的時候拋出異常。
  3. 如果有除GeneratorExit以外的異常被throw到a中的話,該異常 會被直接throw到b中。如果b的throw方法拋出StopIteration, a會繼續執行;其他異常則會導致a也拋出異常。
  4. 如果一個GeneratorExit異常被throw到a中,或者a的close 方法被調用了,并且b也有close方法的話,b的close方法也 會被調用。如果b的這個方法拋出了異常,則會導致a也拋出異常。 反之,如果b成功close掉了,a也會拋出異常,但是是特定的  GeneratorExit異常。
  5. a中yield from表達式的求值結果是b迭代結束時拋出的  StopIteration異常的第一個參數。
  6. b中的return <expr>語句實際上會拋出StopIteration(<expr>) 異常,所以b中return的值會成為a中yield from表達式的返回值。

為神馬會有這么多要求?因為generator這種東西的行為在加入throw 方法之后變得非常復雜,特別是幾個generator在一起的情況,需要 類似進程管理的元語對其進行操作。上面的所有要求都是為了統一 generator原本就復雜的行為,自然簡單不下來啦。

我承認我一下沒看明白PEP的作者到底想說什么,于是動手“重構” 一遍大概會有點幫助。

一個沒用的例子

說沒用是因為你大概不會真的想把程序寫成這樣,但是……反正能說明 問題就夠了。

設想有這樣一個generator函數:

?
1
2
3
4
5
6
7
8
9
10
11
def inner():
 coef = 1
 total = 0
 while True:
 try:
  input_val = yield total
  total = total + coef * input_val
 except SwitchSign:
  coef = -(coef)
 except BreakOut:
  return total

這個函數生成的generator將從send方法接收到的值累加到局部 變量total中,并且在收到BreakOut異常時停止迭代;至于另外 一個SwitchSign異常應該不難理解,這里就不劇透了。

從代碼上看,由inner()函數得到的generator通過send接收用于 運算的數據,同時通過throw方法接受外部代碼的控制以執行不同 的代碼分支,目前為止都很清晰。

接下來因為需求有變動,我們需要在inner()這段代碼的前后分別加 入初始化和清理現場的代碼。鑒于我認為“沒壞的代碼就不要動”,我 決定讓inner()維持現狀,然后再寫一個outer() ,把添加的代碼放在 outer()里,并提供與inner()一樣的操作接口。由于inner()利用了 generator的若干特性,所以outer()也必須做到這五件事情:

  1. outer()必須生成一個generator;
  2. 在每一步的迭代中,outer()要幫助inner()返回迭代值;
  3. 在每一步的迭代中,outer()要幫助inner()接收外部發送的數據;
  4. 在每一步的迭代中,outer()要處理inner()接收和拋出所有異常;
  5. outer()被close的時候,inner()也要被正確地close掉。

根據上面的要求,在只有yield的世界里,outer()可能是長這樣的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def outer1():
 print("Before inner(), I do this.")
 i_gen = inner()
 input_val = None
 ret_val = i_gen.send(input_val)
 while True:
 try:
  input_val = yield ret_val
  ret_val = i_gen.send(input_val)
 except StopIteration:
  break
 except Exception as err:
  try:
  ret_val = i_gen.throw(err)
  except StopIteration:
  break
 print("After inner(), I do that.")

WTF,這段代碼比inner()本身還要長,而且還沒處理close操作。

現在我們來試試外星科技:

?
1
2
3
4
def outer2():
 print("Before inner(), I do this.")
 yield from inner()
 print("After inner(), I do that.")

除了完全符合上面的要求外,這四行代碼打印出來的時候還能省點紙。

我們可以在outer1()outer2()上分別測試 數據 以及 異常 的傳遞,不難發現這兩個generator的行為基本上是一致的。既然如此, 外星科技當然在大多數情況下是首選。

對generator和coroutine的疑問

從以前接觸到Python下的coroutine就覺得它怪怪的,我能看清它們的 行為模式,但是并不明白為什么要使用這種模式,generator和 coroutine具有一樣的對外接口,是generator造就了coroutine呢,還 是coroutine造就了generator?最讓我百思不得其解的是,Python下 的coroutine將“消息傳遞”和“調度”這兩種操作綁在一個yield 上——即便有了yield from,這個狀況還是沒變過——我看不出這樣做 的必要性。如果一開始就從語法層面將這兩種語義分開,并且為 generator和coroutine分別設計一套接口,coroutine的概念大概也會 容易理解一些。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者使用python能帶來一定的幫助,如果有疑問大家可以留言交流。

原文鏈接:http://blog.theerrorlog.com/yield-from-in-python-3.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 成人免费小视频 | 国产成人高清精品免费5388 | 日韩精品视频在线观看一区二区 | 日本韩国欧美一区 | 九九亚洲精品 | 亚洲性片| 免费成人黄色网址 | 久久久99久久久国产自输拍 | 午夜精品久久久久久 | 精品久久久久国产 | 日韩成人在线免费观看 | 紧缚调教一区二区三区视频 | 欧洲一区二区三区 | 国产精品成人3p一区二区三区 | 在线观看av网站永久 | 久久国产欧美日韩精品 | 欧美日韩一区二区在线 | 国产欧美日韩综合精品一区二区 | 欧美在线观看免费观看视频 | 性天堂| 成人av免费观看 | 国产视频一二三区 | a毛片| 日韩精品免费观看 | 日韩成人中文字幕 | 你懂的免费在线观看 | 久久久99精品免费观看 | 久久久国产视频 | 天天干,夜夜操 | 久久国产精品久久精品国产演员表 | 国产精品自拍视频 | 国产精品无码久久久久 | 久操成人 | 日韩欧美在线观看 | 成a人片在线观看 | 韩国毛片在线观看 | 欧美午夜精品 | 中文字幕在线看 | 亚洲精品视频在线看 | 亚洲欧洲精品视频在线观看 | 午夜在线影院 |