作用類似于return,隻不過yield傳回的是一個疊代器(generator),可以配合特殊的方法:next()、send()函數使用。
1.調用:含有yield特殊字的函數,被調用之後傳回的是一個疊代器
def foo():
i = 1
print("starting...")
while True:
yield i+1
i+=1
print(i)
g = foo()
print(g)
》》》
<generator object foo at 0x0000020430EEC8E0>
可以看到,不會執行foo函數的内容,g為一個generator。
2.next(g) 當調用next()函數時,會執行到yield。 nex(g)就是yield傳回的東西。
def foo():
i = 1
print("starting...")
while True:
yield i+1
i+=1
print(i)
g = foo()
print(g)
print(next(g))
print("*"*20)
print(next(g))
》》》
<generator object foo at 0x0000028838AFC8E0>
starting...
2
********************
2
3
再執行next()函數時,會接着上一次next執行完yield的地方繼續向下執行
3.send()函數,指派。否則 yield是不會進行指派操作的。 同時send()方法包含了next()方法,執行send()會自動執行next()
def foo():
i = 1
print("starting...")
while True:
res = yield i+1
i+=1
print(i)
print('res:',res)
g = foo()
print(g)
print(next(g))
print("*"*20)
print(next(g))
》》》
<generator object foo at 0x000001CB255BC8E0>
starting...
2
********************
2
res: None
3
由上面可以看到,雖然有 res = yield i+1,這個貌似指派的操作,但是yield并不會有進行指派
def foo():
i = 1
print("starting...")
while True:
res = yield i+1
i+=1
print(i)
print('res:',res)
g = foo()
print(g)
print(next(g))
print("*"*20)
print(g.send(7))
》》》
<generator object foo at 0x00000187FDD3C8E0>
starting...
2
********************
2
res: 7
3
上段代碼可見,在第一次執行next()函數之後,疊代器會停留在yield處。
在執行g.send(7)時,會接着在yield處繼續執行,進行指派。然後自動再執行next()函數,即運作到下一個yield結束。
4.yield 和 return 的差別
從上面可以看出,yield操作之後,後續是可以繼續有代碼的,下一次next()的時候,後續的代碼也是會被執行的。
而return不同,函數隻要執行了return,這個函數就結束了,return後面的任何代碼是不會被執行的。并且 return沒有标記的作用,不能配合send() 進行指派。