https://blog.csdn.net/chenbin520/article/details/78111399?locationNum=7&fps=1python
一、yield使用
1)函數中使用yield,能夠使函數變成生成器。一個函數若是是生成一個數組,就必須把數據存儲在內存中,若是使用生成器,則在調用的時候才生成數據,能夠節省內存。
2)生成器方法調用時,不會當即執行。須要調用next()或者使用for循環來執行。使用for循環不須要本身捕獲StopIteration異常。使用next()方法,當生產器方法執行結束會拋出StopIteration異常(只要不是使用yield返回數據,都會拋出StopIteration異常)。
示例:數組
def fib(max): n,a,b = 0,0,1 while n < max: yield b a, b = b, a+b n = n + 1 return 'done' n = fib(10) for n1 in n: print(n1)
3)yield不只能夠返回值,也能夠接收值。下面面示例爲生產消費模式。生產者生產一條記錄,消費者消費一條記錄。
4)調用生成器send方法傳遞數據時,必須先調用next(c)或者c.send(None)方法,執行到yield語句,等待接收數據。不然會報錯。
如下代碼爲廖雪峯網站的示例https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090171191d05dae6e129940518d1d6cf6eeaaa969000markdown
def consumer(): r = '' while True: n = yield r if not n: return print('[CONSUMER] Consuming %s...' % n) r = '200 OK' def produce(c): c.send(None) # 和next方法同樣 獲取下一個值,必須先使用None參數調用一次, 執行到yield n = 0 while n < 5: n = n + 1 print('[PRODUCER] Producing %s...' % n) r = c.send(n) # 先發送值給yield語句,再執行到yield語句時返回 print('[PRODUCER] Consumer return:%s' % r) c.close() c = consumer() produce(c)
二、yield from的使用
1)爲了讓生成器(帶yield函數),能簡易的在其餘函數中直接調用,就產生了yield from。
2)如下代碼,htest爲生成器,itest經過yield from 直接調用htest。這樣itest也變成了一個生成器。建立itest實例不斷的去獲取數據,當生成器執行結束時,會拋出StopIteration異常。那這個異常是htest拋出的,仍是itest拋出的。經過捕獲異常,會發現實際上是itest拋出異常,htest並不會拋出StopIteration異常。
3)yield from 也能夠返回值,經過變量接收。變量接收的值,即htest使用return返回的值。示例代碼中,當i==3時,會直接使用return返回,這時val的值就是100;由於htest函數中不是使用yield返回值,因此itest會繼續執行print(val)語句。itest代碼執行完,然而並無使用yield返回數據(htest中沒有,itest中也沒有),因此立刻會拋出StopIteration異常)(若是在itest函數最後使用yield返回一個數據,就不會拋出異常)。函數
def htest(): i = 1 while i < 4: n = yield i if i == 3: return 100 i += 1 def itest(): val = yield from htest() print(val) t = itest() t.send(None) j = 0 while j < 3: j += 1 try: t.send(j) except StopIteration as e: print('異常了')