Python入門篇-生成器函數

              Python入門篇-生成器函數
python

                                      做者:尹正傑async

版權聲明:原創做品,謝絕轉載!不然將追究法律責任。ide

 

 

一.生成器概述函數

1>.生成器generatorspa

  生成器指的是生成器對象,能夠由生成器表達式獲得,也能夠使用yield關鍵字獲得一個生成器函數,調用這個函數獲得一個生成器對象

2>. 生成器函數線程

  函數體中包含yield語句的函數,返回生成器對象

  生成器對象,是一個可迭代對象,是一個迭代器

  生成器對象,是延遲計算,惰性求值的

  包含yield語句的生成器函數生成生成器對象的時候,生成器函數的函數體不會當即執行

  next(generator)會從函數的當前位置向後執行到以後碰到的第一個yield語句,會彈出值,並暫停函數執行

  再次調用next函數,和上一條同樣的處理過程
  
  沒有多餘的yield語句能被執行,繼續調用next函數,會拋出StopIteration異常
  

3>.編寫一個生成器函數樣例code

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 """
 8 關於生成器函數的相關說明:
 9 
10     在生成器函數中,使用多個yield語句,執行一次後會暫停執行,把yield表達式的值返回
11     
12     再次執行會執行到下一個yield語句
13     
14     return 語句依然能夠終止函數運行,但return語句返回值不能被捕獲到
15     
16     return 會致使沒法繼續獲取下一個值,拋出StopIteration異常
17     
18     若是函數沒有顯示的return語句,若是生成器函數執行到結尾,同樣會拋出StopIteration異常喲
19 
20 """
21 def gen():
22     print('line 1')
23     yield 1
24     print('line 2')
25     yield 2
26     print('line 3')
27     return 3
28 
29 next(gen())
30 
31 next(gen())
32 
33 g = gen()
34 
35 print(next(g))
36 print(next(g))
37 
38 # print(next(g))              #報錯:StopIteration: 3,由於已經沒有多餘的yield語句啦,上面已經被調用兩次了
39 
40 print(next(g, 'End'))         #若是沒有元素就給個缺省值
41 
42 
43 
44 #以上代碼執行結果以下:
45 line 1
46 line 1
47 line 1
48 1
49 line 2
50 2
51 line 3
52 End

 

二.生成器應用協程

1>.無限循環對象

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 
 8 def counter():
 9     i = 0
10     while True:
11         i += 1
12         yield i
13 
14 def inc(c):
15         return next(c)
16 
17 c = counter()           #這是一個生成器對象
18 
19 print(inc(c))
20 print(inc(c))
21 
22 
23 
24 #以上代碼輸出結果以下:
25 1
26 2

2>.計數器blog

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 def inc():
 8     def counter():
 9         i = 0
10         while True:
11             i += 1
12             yield i
13     c = counter()
14     return lambda : next(c)  #這裏返回的是匿名函數
15 
16 foo = inc()
17 print(foo())
18 print(foo())
19 
20 
21 
22 #以上代碼輸出結果以下:
23 1
24 2

3>.處理遞歸問題

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 
 8 def fib():
 9     x = 0
10     y = 1
11     while True:
12         yield y
13         x, y = y, x+y
14 
15 foo = fib()
16 
17 for _ in range(5):
18     print(next(foo))
19 
20 for _ in range(100):
21     next(foo)
22 
23 print(next(foo))
24 
25 
26 #以上代碼輸出結果以下:
27 1
28 1
29 2
30 3
31 5
32 6356306993006846248183
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com


pre = 0
cur = 1
print(pre,cur,end=" ")

def fib(n,pre=0,cur=1):
    pre,cur = cur,pre + cur
    print(cur,end=" ")
    if n == 2:
        return
    fib(n-1,pre,cur)



fib(106)
以上代碼改寫成遞歸方式戳我~

4>.協程(coroutine)

(1)生成器的高級用法

(2)比進程,線程輕量級

(3)是在用戶空間調度的一種實現

(4)Python3 asyncio就是協程實現,已經加入到標準庫

(5)Python3.5 使用async,await關鍵字直接原生支持協程
協程調度器實現思路:
    有2個生成器A,B
    next(A)後,A執行到了yield語句暫停,而後去執行next(B),B執行到yield語句也暫停,而後再次調用next(A),再調用next(B),周而復始,就實現了調度的效果
    能夠引入調度的策略來實現切換的方式

(6)協程就是一種非搶佔式調度

 

三.yield from

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 
 8 def inc():
 9     for x in range(1000):
10         yield x
11 
12 foo = inc()
13 print(next(foo))
14 print(next(foo))
15 print(next(foo))
16 
17 print("*" * 20 + "我是分割符" +"*" * 20)
18 
19 """
20     以上代碼能夠使用yield from代碼改寫,等價於下的代碼:
21 """
22 def inc():
23     yield from range(1000)
24 
25 bar = inc()
26 print(next(bar))
27 print(next(bar))
28 print(next(bar))
29 
30 
31 
32 #以上代碼輸出結果以下:
33 0
34 1
35 2
36 ********************我是分割符********************
37 0
38 1
39 2
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com


"""
yield from是Python 3.3出現新的語法

yield from iterable 是 for item in iterable: yield item 形式的語法糖

"""

#從可迭代對象中一個個拿元素
def counter(n):
    for x in range(n):
        yield x

def inc(n):
    yield from counter(n)

foo = inc(10)
print(next(foo))
print(next(foo))



#以上代碼執行結果以下:
0
1
yield from是Python 3.3出現新的語法
相關文章
相關標籤/搜索