Python中yield和yield from的用法
yield
python中yield的用法很像return,都是提供一個(gè)返回值,但是yield和return的最大區(qū)別在于,return一旦返回,則代碼段執(zhí)行結(jié)束,但是yield在返回值以后,會(huì)交出CUP的使用權(quán),代碼段并沒(méi)有直接結(jié)束,而是在此處中斷,當(dāng)調(diào)用send()或者next()方法之后,yield可以從之前中斷的地方繼續(xù)執(zhí)行。
在一個(gè)函數(shù)中,使用yield關(guān)鍵字,則當(dāng)前的函數(shù)會(huì)變成生成器。
下面生成一個(gè)斐波那契數(shù)列。
def fib(n):
index = 0
a = 0
b = 1
while index < n:
yield b
a,b = b, a+b
index += 1
生成器對(duì)象
fib = fib(100)
print(fib)
打印出來(lái)的結(jié)果是一個(gè)生成器對(duì)象,并沒(méi)有直接把我們想要的值打印出來(lái)。
next()方法
fib = fib(100)
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
它的執(zhí)行順序是這樣的,每次yield返回之后,程序?qū)?huì)中斷,當(dāng)出現(xiàn)next(fib)之后,程序?qū)?huì)從之前中斷的地方繼續(xù)執(zhí)行。 python新版本中,不再提供fib.next()方法。
send()方法
使用send()方法允許我們向生成器中傳值。
import time
def fib(n):
index = 0
a = 0
b = 1
while index < n:
sleep = yield b
print('等待%s秒' %sleep)
time.sleep(sleep)
a,b = b, a+b
index += 1
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))
執(zhí)行順序如下:
首先,創(chuàng)建生成器對(duì)象
調(diào)用fib.send(None)方法,此處作用與next(fib)相同,程序返回當(dāng)前b的值1, 程序中斷。
調(diào)用fib.send(2)方法,程序被喚醒,將2傳遞給yield之前的變量sleep,程序繼續(xù)運(yùn)行,直到遇到y(tǒng)ield將新的b返回,程序再次中斷。
如此繼續(xù)下去,直到程序結(jié)束。
yield from
前面的都是單一層次的生成器,并沒(méi)有嵌套,如果是多個(gè)生成器嵌套會(huì)怎么樣呢,下面是一個(gè)例子。
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
if __name__ == '__main__':
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))
在兩層嵌套的情況下,值的傳遞方式是,先把值傳遞給外層生成器,外層生成器再將值傳遞給外層生成器,內(nèi)層生成器在將值反向傳遞給外層生成器,最終yield出結(jié)果。如果嵌套的層次更多,傳遞將會(huì)越麻煩。
下面是yield from的實(shí)現(xiàn)方式:
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))
效果是一樣的,但是明顯的代碼量減少了,嵌套傳值的時(shí)候,并不需要我們手動(dòng)實(shí)現(xiàn)。
總結(jié)
以上是生活随笔為你收集整理的Python中yield和yield from的用法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 分类数据表设计的简单再总结
- 下一篇: Word文件交换的电脑打开字体、排版变化