生成器可以簡單有效的建立龐大的可迭代物件,而不需要在直接在記憶體中建立儲存整個序列
可以使用生成器推導式或者生成器函式來建立生成器
生成器函式返回資料時使用yield語句,而不是使用return
>>> def countdown(n):
... print("counting down from %d" %n)
... while n>0:
... yield n
... n -=1
... return 'done'
...>>> c = countdown(10) #c為乙個生成器物件
可以通過next()函式或者生成器物件的__next__()方法來獲得生成器的下乙個返回值
當計算到最後乙個元素後,沒有更多的元素時,丟擲stopinteration,生成器終止
>>> c = countdown(3)
>>> next(c)
counting down from 3
3>>> c.__next__()
2>>> next(c)
1>>> next(c)
traceback (most recent call last):
file "", line 1, in stopiteration: done
通常直接通過for迴圈來迭代生成器,並且不需要關心stopinteration
但是用for迴圈呼叫生成器時,發現拿不到生成器的return語句的返回值。
如果想要拿到返回值,必須捕獲stopinteration錯誤,返回值包含在stopinteration的value中
>>> while true:
... try:
... x = next(c)
... print(c)
... except stopiteration as e:
... print('generator return value:', e.value)
... break
...
當乙個生成器沒有全部迭代完成,但是不在使用了,可以呼叫close()方法關閉生成器,通常不必手動呼叫close()方法
c = countdown(10)
>>> next(c)
1>>> c.close()
>>> next(c)
traceback (most recent call last):
file "", line 1, in stopiteration
協程可以理解為就像生成器那樣可以暫停的函式
在函式內,當yield語句作為表示式使用,出現在賦值運算子的右邊,在向函式傳送值時函式將執行
這種生成器函式可以被稱為協程函式,而對協程函式的呼叫可以獲得協程物件
"協程"一詞可以用於協程函式和協程物件
>>> def coroutine():
... print("start coroutine")
... r = 'ok'
... while true:
... n = yield r
... print('receiver %s' % n)
...>>> c = coroutine()
>>> c.send(1)
traceback (most recent call last):
file "", line 1, in typeerror: can't send non-none value to a just-started generator
>>> c.send(none) #next(c)
start coroutine
'ok'
>>> c.send(1)
receiver 1
'ok'
>>> c.close()
>>> c.send(2)
traceback (most recent call last):
file "", line 1, in stopiteration
在傳送資料之前,應該呼叫c.send(none)啟動生成器或者使用next()函式,使協程執行第乙個yield之前的語句
啟動後協程會掛起,等待協程物件c的send()方法傳送值
yield語句會接收send()傳送的值,並返回yield 語句後的值
協程一般會不斷執行下去,可以通過close()方法關閉協程
我們可以使用asyncio模組中的@asyncio.coroutine裝飾器來使協程函式在呼叫時自動執行到yield語句前,而不需要提前呼叫send(none)或next()函式
具體的asyncio模組和協程的講解可以看另一篇文章
python迭代器生成器協程
迭代器有兩個基本的方法 iter 和next 把乙個類作為乙個迭代器使用需要在類中實現兩個方法iter 與next stopiteration 異常用於標識迭代的完成 class mylist object def init self self.items def iter self iter my...
python 生成器協程運算例項
一 yield執行方式 我們定義乙個如下的生成器 def put on name print hi 貨物來了,準備搬到倉庫!format name while true goods yield print 貨物 s 已經被 s搬進倉庫了。goods,name p put on bigberg 輸出g...
Python生成器函式 yield 協程應用
生成器應用 m i for i in range 5 print type m 列印結果 型別 生成器 print next m 列印結果 0 definc for i in range 5 yield i print type inc 列印結果 型別 函式 print type inc 列印結果 ...