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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Python中yield和yield from的用法

發布時間:2023/11/28 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python中yield和yield from的用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

yield 后面接的是 future 對象
調用方 委托生成器
yield from 直接給出循環后的結果
yield from 委托者和子生成器直接通信
yield from 直接處理stopIteration錯誤 并把結果返回
jieshou=yield chuanchu
左邊是接收值 右邊是傳入值 既是生產者也是消費者

調用方 main 委托方 子生成器(位于委托方內部)
yield 同時接受值傳遞給等號左邊的變量,同時返回其后面的變量給外面的函數

yield from 總結
看完代碼,我們總結一下關鍵點:

  1. 子生成器生產的值,都是直接傳給調用方的;調用方通過.send()發送的值都是直接傳遞給子生成器的;如果發送的是 None,會調用子生成器的__next__()方法,如果不是 None,會調用子生成器的.send()方法;
  2. 子生成器退出的時候,最后的return EXPR,會觸發一個StopIteration(EXPR)異常;
  3. yield from表達式的值,是子生成器終止時,傳遞給StopIteration異常的第一個參數;
  4. 如果調用的時候出現StopIteration異常,委托生成器會恢復運行,同時其他的異常會向上 “冒泡”;
  5. 傳入委托生成器的異常里,除了GeneratorExit之外,其他的所有異常全部傳遞給子生成器的.throw()方法;如果調用.throw()的時候出現了StopIteration異常,那么就恢復委托生成器的運行,其他的異常全部向上 “冒泡”;
  6. 如果在委托生成器上調用.close()或傳入GeneratorExit異常,會調用子生成器的.close()方法,沒有的話就不調用。如果在調用.close()的時候拋出了異常,那么就向上 “冒泡”,否則的話委托生成器會拋出GeneratorExit異常。

協程:子生成器報錯會直接把錯誤返回給調用方
和函數調用差不多 和同步編碼方式一樣

協程里面耗時的操作 比如 IO,time.sleep 等不能單獨成行
卸載內部 只能放在yield 或者 yield from 后面

def fun_inner():
i = 0
while True:
i = yield i #傳什么就返回什么

def fun_outer():
a = 0
b = 1
inner = fun_inner()
inner.send(None)
while True:
a = inner.send(b)
b = yield a #b原來不管是什么值 都會變成傳入的值,傳出的值為a

if name == ‘main’:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))

下面是yield from的實現方式:

def fun_inner():
i = 0
while True:
i = yield i

def fun_outer():
yield from fun_inner() #直接返回另一個生成器產生的值
直接調用另一個生成器

if name == ‘main’:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))

Python中yield和yield from的用法

        </h1><div class="clear"></div><div class="postBody">

yield

python中yield的用法很像return,都是提供一個返回值,但是yield和return的最大區別在于,return一旦返回,則代碼段執行結束,但是yield在返回值以后,會交出CUP的使用權,代碼段并沒有直接結束,而是在此處中斷,當調用send()或者next()方法之后,yield可以從之前中斷的地方繼續執行。

在一個函數中,使用yield關鍵字,則當前的函數會變成生成器。

下面生成一個斐波那契數列。

def fib(n):index = 0a = 0b = 1
<span class="hljs-keyword">while</span> index &lt; <span class="hljs-symbol">n:</span><span class="hljs-keyword">yield</span> ba,b = b, a+bindex += <span class="hljs-number">1</span></code></pre>
  1. 生成器對象
fib = fib(100)
print(fib)


打印出來的結果是一個生成器對象,并沒有直接把我們想要的值打印出來。

  1. next()方法
fib = fib(100)
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))

它的執行順序是這樣的,每次yield返回之后,程序將會中斷,當出現next(fib)之后,程序將會從之前中斷的地方繼續執行。 python新版本中,不再提供fib.next()方法。

  1. send()方法

使用send()方法允許我們向生成器中傳值。

import time

def fib(n):
index = 0
a = 0
b = 1

<span class="hljs-keyword">while</span> <span class="hljs-keyword">index</span> &lt; n:<span class="hljs-keyword">sleep</span> = yield b<span class="hljs-keyword">print</span>(<span class="hljs-string">'等待%s秒'</span> %sleep)time.sleep(<span class="hljs-keyword">sleep</span>)a,b = b, a+b<span class="hljs-keyword">index</span> += <span class="hljs-number">1</span>

fib = fib(20)
print(fib.send(None)) # 效果等同于print(next(fib))
print(fib.send(2))
print(fib.send(2))
print(fib.send(2))
print(fib.send(2))

執行順序如下:
首先,創建生成器對象
調用fib.send(None)方法,此處作用與next(fib)相同,程序返回當前b的值1, 程序中斷。
調用fib.send(2)方法,程序被喚醒,將2傳遞給yield之前的變量sleep,程序繼續運行,直到遇到yield將新的b返回,程序再次中斷。
如此繼續下去,直到程序結束。

yield from

前面的都是單一層次的生成器,并沒有嵌套,如果是多個生成器嵌套會怎么樣呢,下面是一個例子。

def fun_inner():i = 0while True:i = yield i

def fun_outer():
a = 0
b = 1
inner = fun_inner()
inner.send(None)
while True:
a = inner.send(b)
b = yield a

if name == main:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))

在兩層嵌套的情況下,值的傳遞方式是,先把值傳遞給外層生成器,外層生成器再將值傳遞給外層生成器,內層生成器在將值反向傳遞給外層生成器,最終yield出結果。如果嵌套的層次更多,傳遞將會越麻煩。

下面是yield from的實現方式:

def fun_inner():i = 0while True:i = yield i

def fun_outer():
yield from fun_inner()

if name == main:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))

效果是一樣的,但是明顯的代碼量減少了,嵌套傳值的時候,并不需要我們手動實現。

分類: Python
<div id="blog_post_info">
好文要頂 關注我 收藏該文 cnkai
關注 - 0
粉絲 - 85 +加關注 0 0
<div class="clear"></div>
<div id="post_next_prev"><a href="https://www.cnblogs.com/cnkai/p/7514815.html" class="p_n_p_prefix">? </a> 上一篇:    <a href="https://www.cnblogs.com/cnkai/p/7514815.html" title="發布于 2017-09-13 14:35">Python多進程</a>
<br>
<a href="https://www.cnblogs.com/cnkai/p/7538260.html" class="p_n_p_prefix">? </a> 下一篇:    <a href="https://www.cnblogs.com/cnkai/p/7538260.html" title="發布于 2017-09-17 22:28">Selenium快速入門(上)</a>
posted @ 2017-09-13 14:36?cnkai 閱讀(1480) 評論(0) 編輯 收藏
</div>
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20191018154227110.jpg)

總結

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

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