1 def fib(max): 2 n,a,b = 0,0,1 3 while n < max: 4 print(b) 5 a,b = b,a+b 6 n = n + 1 7 return 'done' 8 9 10 fib(10) 11 #注意賦值語句:a,b = b,a+b 12 13 14 a,b = b,a+b 15 1,1 = 1,0+1 16 1 ,2 = 1,1+1 17 2,3 = 2,1+2 18 3,5 = 3,2+3 19 5,8 = 5,3+5 20 8,13 = 8,5+8 21 13,21= 13,8+13
1 #將print改成yeild: 2 def fib(max): 3 n,a,b = 0,0,1 4 while n < max: 5 #print(b) 6 yield b 7 a,b = b,a+b 8 n = n + 1 9 return 'done' 10 11 ret = fib(10) 12 print(ret) 13 14 15 #顯示結果: 16 <generator object fib at 0x0000000000B387D8>
每執行一個ret.__next__(),就調用一次。python
1、優勢:nginx
每一次調用就會中斷退出,而後在調用在退出,以此類推。
例如:每調用一次,程序就會退出,而後在去作別的事兒,作完在用ret.__next__(),調用下一個生成器。多線程
1 def fib(max): 2 n,a,b = 0,0,1 3 while n < max: 4 #print(b) 5 yield b 6 a,b = b,a+b 7 n = n + 1 8 return 'done' 9 10 ret = fib(10) 11 print(ret) 12 print(ret.__next__()) 13 print(ret.__next__()) 14 print(ret.__next__())
2、缺點:併發
__next__()調用超出迭代器的範圍,因此報錯。
生產中是不知道迭代器的元素有多少,因此只能等待異常的出現。異步
所以能夠用異常處理來抓住生成器的結束,以下:ide
1 def fib(max): 1 6 2 n,a,b = 0,0,1 7 3 while n < max: 8 16 4 #print(b) 5 yield b 9 13 17 #中斷退出,並將至返回給next() 6 a,b = b,a+b 14 7 n = n + 1 15 8 return '異常' 9 10 g = fib(6) 2 11 12 while True: 3 11 13 try: 4 14 #內置方法,與__next__()是同樣的,返回到上一次yield中斷的地方 15 x = next(g) 5 12 16 print('g:',x) 10 18 17 except StopIteration as e: 18 print('Generator return values:',e.value) 19 break
1、概念:cpu調用程序分爲:進程--(包含多個)-->線程--(包含多個)-->協程函數
2、做用:經過生成器yield實現單線程的狀況下實現併發運算效果(異步IO的雛形)。spa
3、工做原理:線程
1、生成器只有在調用時纔會生成相應的數據 二、調用方式有 " str__next__.() str.send() ", 3、而且每調用一次就產生一個值調用到最後一個值後會報錯 四、報錯可用try和except作異常處理
5、實例:3d
1 #!/usr/bin/env python 2 # -*- coding:utf8 -*- 3 # Author:Dong Ye 4 5 6 ''' 7 定義兩個模型: 8 一個是生產包子的。(生成器) 9 另外一個是吃包子的。(迭代器) 10 11 這段功能實現了異步IO的雛形,也是一個簡單的協程處理方式。 12 協程的特色:實際是串行方式分開執行的,但因爲運行效果快,給人的感受像是並行。 13 所以,協程也叫做:單線程下的並行執行效果。 14 協程是包含在線程裏的一個單位,線程時進程的一個單位。 15 例如:enginx在異步單線程下,比多線程要快好多倍,也就是這種效果。 16 ''' 17 18 import time 19 20 21 #吃包子的 22 def consumer(name): 23 print('%s 準備吃包子了!' % name) 24 while True: 25 baozi = yield 26 print("包子[%s]來了。被[%s]吃了!" %(baozi,name)) 27 28 29 #生產包子的 30 def producer(name): 31 #先定義2個協程(消費者)#將函數變成生成器 32 c1 = consumer('A') #2個消費者 33 c2 = consumer('B') #至關於2個協程(進程,線程,協程) 34 #開始調用生成器初始化(準備吃包子) 35 c1.__next__() #開始調用生成器,只有next的時候纔會到yield進行下一個操做 36 c2.__next__() 37 print('老子開始吃包子拉!') 38 #循環的次數,每次循環都會傳值給生成器(產生什麼樣的包子) 39 for i in range(10): 40 time.sleep(1) 41 print("作了一個包子,分2半,一人一半") 42 c1.send(i) #包子的類型 43 c2.send(i) 44 45 46 producer("alex") 47 48 49 50 ''' 51 #手動作包子: 52 c = consumer("dy") 53 c.__next__() 54 #c.__next__() 55 56 b1 = "韭菜餡" 57 c.send(b1) #調用+傳值 58 #c.__next__() #只調用,不傳值 59 ''' 60 61 62 63 顯示結果: 64 A 準備吃包子了! 65 B 準備吃包子了! 66 老子開始吃包子拉! 67 作了一個包子,分2半,一人一半 #任務1 68 包子[0]來了。被[A]吃了! #任務2 69 包子[0]來了。被[B]吃了! #任務3 70 作了一個包子,分2半,一人一半 71 包子[1]來了。被[A]吃了! 72 包子[1]來了。被[B]吃了! 73 作了一個包子,分2半,一人一半 74 包子[2]來了。被[A]吃了! 75 包子[2]來了。被[B]吃了! 76 作了一個包子,分2半,一人一半 77 包子[3]來了。被[A]吃了! 78 包子[3]來了。被[B]吃了! 79 作了一個包子,分2半,一人一半 80 包子[4]來了。被[A]吃了! 81 包子[4]來了。被[B]吃了! 82 作了一個包子,分2半,一人一半 83 包子[5]來了。被[A]吃了! 84 包子[5]來了。被[B]吃了! 85 作了一個包子,分2半,一人一半 86 包子[6]來了。被[A]吃了! 87 包子[6]來了。被[B]吃了! 88 作了一個包子,分2半,一人一半 89 包子[7]來了。被[A]吃了! 90 包子[7]來了。被[B]吃了! 91 作了一個包子,分2半,一人一半 92 包子[8]來了。被[A]吃了! 93 包子[8]來了。被[B]吃了! 94 作了一個包子,分2半,一人一半 95 包子[9]來了。被[A]吃了! 96 包子[9]來了。被[B]吃了!