有如下函數:
def gen():
li = [1, 2, 3, 4]
for i in li:
yield i
a = gen()
try:
while True:
print(a.next())
except StopIteration:
print('generator ({}) has finished.'.format('a'))
print(gen)
print(a)
這裏,gen是個函數,而a是個生成器
所以輸出:
1
2
3
4
generator (a) has finished.
<function gen at 0x7f010d70c410> #gen果然是個函數
<generator object gen at 0x7f010d748d70> #a的確是個生成器
所以針對a,就把它當作一個類的實例來處理。
而如何給生成器發信息呢?
首先,生成器得有東西接收我們發的信息吧,如下添加:
def gen():
li = [1, 2, 3, 4]
for i in li:
recvor1 = yield i
print('generator received: {}'.format(recvor1))
這樣的話,給生成器發的信息會被存儲到recvor1中,那麼如何如何向生成器發送信息呢?
使用生成器的方法:send()
原型:
generator.send(value)
value僅僅表示說個值,你可以傳遞任何值,只要在生成器內部用匹配的結構接收就可以了知道了方法,如何操作呢?
print(a.next())
print(a.send(15))
輸出:
1
generator received: 15
2
由於使用生成器的時候,第一次必須調用next,所以先調用next()方法,爲什麼呢?
看如下生成器的路由:
用戶調用next()->
開始進入gen->
創建li->
進入循環,執行第一次i的取值->
yield i 返回i,暫停生成器
用戶再次執行next()->
生成器繼續執行,從recvor = ...開始->
執行print語句->
第二次進入循環,爲i取值->
yield i返回i,暫停生成器
用戶再次執行next()->
生成器繼續執行,從recvor = ...開始->
執行print語句->
第三次進入循環,爲i取值->
yield i返回i,暫停生成器
直到StopIteration異常發生退出生成器
上面是個人總結。可以看出,使用send發信息,只有從第二次循環的yield才能接收數據,第一次沒有人接收
來發送一個元組試試:
def gen():
li = [1, 2, 3, 4]
for i in li:
tuple1 = yield i
print('generator received: {}'.format(tuple1))
a = gen()
print(a.next())
print(a.send((15, 16)))
輸出:
1
generator received: (15, 16)
2
那麼,如果沒有發送值,而是調用了next方法,會如何呢?首先,得知道next等同於send(None)def gen():
li = [1, 2, 3, 4]
for i in li:
tuple1 = yield i
print('generator received: {}'.format(tuple1))
a = gen()
print(a.next())
print(a.next())
print(a.next())
print(a.send((15, 16)))
輸出:
1
generator received: None
2
generator received: None
3
generator received: (15, 16)
4
介紹完了。還有一點要備註,對於沒有正常執行完畢的生成器,即沒有拋出StopIteration異常的生成器,要調用close關閉它
def gen():
li = [1, 2, 3, 4]
for i in li:
tuple1 = yield i
print('generator received: {}'.format(tuple1))
a = gen()
try:
print(a.next())
while True:
val = a.send(15)
print(val)
if val == 3:
a.close()#要關閉
break
except StopIteration:
print('generator ({}) has finished.'.format('a'))