Python探險--生成器yield剖析

日期:20170926


本次運行環境Python3


我們先來看一下代碼,

#!/usr/bin/python3

def MyGenerator():
        yield 1
        yield 2
        yield 3
        return "done"

print(MyGenerator)
print()
Num=MyGenerator()
print(Num)
print(next(Num))
print(next(Num))
print(next(Num))

運行,

[penx@ali01 python2]$ ./example_generator.py 
<function MyGenerator at 0x7f297bff99d8>

<generator object MyGenerator at 0x7f297bf57708>
1
2
3
[penx@ali01 python2]$ 

運行過程,
先print出MyGenerator的信息,可以看出它只是一個函數。

再調用MyGenerator,返回給Num。雖然MyGenerator是函數,但這裏並沒有執行。好戲在後頭。

我print出Num的信息,卻是一個“generator object”。調用一個函數不但沒有執行,反而返回了一個對象,generator object。對象通常可以理解爲實例。
很奇怪,對吧?Python把生成器的信息標誌爲函數(function),但調用時卻生成一個實例。有可能Python把函數解析封裝成一個生成器。

用next(Num)開始執行生成器函數,執行到yield 1時,返回並返回n。

再next,就會再次進入生成器函數,但並不是重頭執行,而是上一次的yield 1後。遇到yield 2,再次返回。

再next,情況類似。

如果再加一個next,就會報StopIteration。


剖析,

其實yield並不神祕,其實就是我們學習操作系統時,任務掛起的知識點。
函數通過yield自己掛起,然後我們可以用next來喚醒它。
因爲yield掛起時,會保存運行環境,所以next就可以知道函數運行到哪一步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章