自學Python之路-Python基礎+模塊+面向對象
自學Python之路-Python網絡編程
自學Python之路-Python併發編程+數據庫+前端
自學Python之路-djangohtml
定義:生成器(generator)是一個包含yield關鍵字的函數,當它被調用的時候,在函數體中的代碼不會被執行,而是會返回一個迭代器。
(一個函數調用時返回一個迭代器,那這個函數就叫作生成器(generator);
若是函數中包含yield語法,那這個函數就會變成生成器;)前端
python提供了兩種基本的生成器方式:python
爲何叫生成器函數?由於他隨着時間的推移生成了一個數值隊列。通常的函數在執行完畢以後會返回一個值而後退出,可是生成器函數會自動掛起,而後從新拾起繼續執行,他會利用yield關鍵字關起函數,給調用者返回一個值,同時保留了當前的足夠多的狀態,可使函數繼續執行。
生成器和迭代協議是密切相關的,可迭代的對象都有一個__next()__成員方法,這個方法要麼返回迭代的下一項,要麼引發異常結束迭代。
爲了支持迭代協議,擁有yield語句的函數被編譯爲生成器,這類函數被調用時返回一個生成器對象,返回的對象支持迭代接口,即成員方法__next()__繼續從中斷處執行執行。數據庫
def func(): #func是函數稱爲生成器,當執行此函數func()時會獲得一個迭代器。 yield 1 yield 2 yield 3 yield 4 temp = func() print(temp.__next__()) print(temp.__next__()) print(temp.__next__()) print(temp.__next__())
def creat_counter(n): print('create counter') while True: yield n print('increment n') n += 1 cnt = creat_counter(2) print(cnt) print(next(cnt)) print(next(cnt)) print(next(cnt))
分析以上的列子:django
def cube(n): for i in range(n): yield i ** 3 for i in cube(5): print(i)
從理解函數的角度出發咱們能夠將yield類比爲return,可是功能確實徹底不一樣,在for循環中,會自動遵循迭代規則,每次調用next()函數,因此上面的結果不難理解。編程
舉例1:數組
舉例2:網絡
舉例3: 取不到值會報錯併發
舉例4: 使用for循環取值函數
舉例5.1 : 打印出10個哇哈哈
舉例5.2 :若是如今有10個哇哈哈, 我如今只想用5個
迭代器依舊延續向下走:
舉例6:
def generator(): print('123') content = yield 1 print('=========',content) print(456) yield 2 g = generator() ret = g.__next__() print("******",ret) ret = g.send("hello") print("**********",ret)
send 獲取下一個值的效果和next基本一致,只是在獲取下一個值得時候,給上一個yield的位置傳遞一個數據
使用send的注意事項:
舉例7.1:
獲取移動平均值:
10 20 30 10
15 20 17.5
def average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num count += 1 avg = sum/count avg_g = average() avg_g.__next__() avg1 = avg_g.send(10) avg1 = avg_g.send(20) avg1 = avg_g.send(30) print(avg1)
舉例7.2: 預激生成器的裝飾器完成獲取移動平均值
def init(func): #裝飾器 def inner(*args,**kwargs): g = func(*args,**kwargs) #g = average() g.__next__() return g return inner @init def average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num # 10 count += 1 # 1 avg = sum/count avg_g = average() #===> inner ret = avg_g.send(10) print(ret) ret = avg_g.send(20) print(ret)
以上程序執行步驟:
舉例8 :
在python3裏面的新功能 yield from
.