Python生成器-博文讀后感


Windows 10家庭中文版,Python 3.6.4,

 

上午看過了一篇講Python生成器的博文:

提高你的Python: 解釋‘yield’和‘Generators(生成器)’ 英文原文

 

這篇博文講的挺好的,但在讀完后,自己仍然對yield、send、yield返回值等概念不清楚,於是,做了兩個小試驗。

 

試驗一:yield語句的返回值

 1 def xyz():
 2     print('xyz 0')
 3     while True:
 4         print('xyz 1')
 5         data = yield 2
 6         print('xyz 2, data = ', data)
 7 
 8 if __name__ == '__main__':
 9     mg = xyz()
10     for _ in range(3):
11         print('\nmain: _ = ', _)
12         print('main:', next(mg))

 

結果:

main: _ = 0
xyz 0
xyz 1
main: 2

main: _ = 1
xyz 2, data = None
xyz 1
main: 2

main: _ = 2
xyz 2, data = None
xyz 1
main: 2

 

介紹:

定義了生成器函數xyz(),使用語句data = yield 2

舊的想法:data會等於2;

測試結果:data等於None;

 

執行next(mg)函數時,控制權交給了xyz()函數——第一次執行xyz()函數,輸出了xyz 0,再進入循環,執行yield語句;

yield生成了2,控制權和生成的值2返回給調用函數——語句執行完畢后會給data賦值吧?或者等下一次給data賦值?,輸出main: 2;

此時,生成器停在了這里;

 

再次執行next(mg)時,控制器又交給了xyz()函數,從上一次執行yield語句的下一句開始執行,於是,輸出了“xyz 2, data = None”,上一次執行yield時,給data的值居然是None,孤以為會是2呢!

 

試驗二:生成器的send函數和yield返回值語句的關系

 1 def xyz():
 2     print('xyz 0')
 3     while True:
 4         print('xyz 1')
 5         data = yield 2
 6         print('xyz 2, data = ', data)
 7 
 8 if __name__ == '__main__':
 9     print('main 0')
10     mg = xyz()
11     print('main 1')
12     mg.send(None) # 第一次必須如此!!! 13     print('main 2')
14     for _ in range(3):
15         print('\nmain 3')
16         mg.send(_)
17         print('main 4')

 

結果:

main 0
main 1
xyz 0
xyz 1
main 2

main 3
xyz 2, data = 0
xyz 1
main 4

main 3
xyz 2, data = 1
xyz 1
main 4

main 3
xyz 2, data = 2
xyz 1
main 4

 

介紹:

第一次必須執行mg.send(None),為什么這樣孤還沒搞清楚,和生成器的內部實現有關;

在調用send函數時,控制權交給xyz()函數,執行到yield語句停止,再將控制器返回給調用函數;

主函數中循環執行send函數;

第一次發送了0,結果輸出xyz 2, data = 0,這里的data不是None了,即便之前有調用send(None),這是否可以認為,yield語句是在 控制權交給生成器所在函數后才執行的?

xyz()中的循環執行到print('xyz 1')再次停止,控制器返回給主函數;

之后再把1、2發送給生成器;

 

總結

next(generator), generator.send(data)都會將控制權交給生成器函數;

yield語句是在獲取控制權后執行,而不是之前,之前程序掛在這里了,同時保存了上下文;

 

下面三條語句的解釋:

yield # 返回給主調函數None

data = yield # 返回給主調函數None,並把send的值賦值給data;如果是使用next獲取了控制權,那么,調用next處獲得None;

data = yield 2 # 返回給主調函數next(),並把send的值賦值給data;

 

本文開頭的博文大家要看看,這樣才可以更好地理解孤這篇文檔,結合那篇博文及這兩個試驗,孤以為自己掌握了Python生成器的80%了吧,更多就需要看官網了。

 

----

 

本來想找個Python官方鏈接給大家的,可是啊,它的這個頁面一時訪問不了(為什么呢?):大家自行搜索官方、權威文檔吧,也會講解的更詳細。

https://docs.python.org/3/tutorial/index.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM