生成器generatorpython
生成器指的是生成器對象,能夠由生成器表達式獲得,也能夠使用yield關鍵字獲得一個生成器函數,async
調用這個函數獲得一個生成器對象ide
生成器函數函數
函數體中包含yield語句的函數,返回生成器對象線程
生成器對象,是一個可迭代對象,是一個迭代器調試
生成器對象,是延遲計算、惰性求值的協程
def inc(): for i in range(5): yield i print(type(inc)) print(type(inc())) x = inc() print(type(x)) print(next(x)) for m in x: print(m, '*') for m in x: print(m, '**')
普通的函數調用fn(),函數會當即執行完畢,可是生成器函數能夠使用next函數屢次執行
對象
生成器函數等價於生成器表達式,只不過生成器函數能夠更加複雜遞歸
def gen(): print("line 1") yield 1 print("line 2") yield 2 print("line 3") yield 3 next(gen()) next(gen()) g =gen() print(next(g)) print(next(g)) print(next(g)) print(next(g, 'End')) print(next(g, 'End'))
總結:
進程
包含yield語句的生成器函數生成 生成器對象 的時候,生成器函數的函數體不會當即執行;
next(generator)會從函數的當前位置向後執行到以後碰到的第一個yield語句,會彈出值,並暫停函數執行;
再次調用next函數,和上一條同樣的處理過程;
沒有多餘的yield語句能被執行,繼續調用next函數,會拋出StopIteration異常。
生成器應用
無限循環
def counter(): i = 0 while True: i += 1 yield i def inc(c): return next(c) c = counter() print(inc(c)) print(inc(c))
計數器: def inc(): def counter(): i = 0 while True: i += 1 yield i c = counter() return lambda : next(c) foo = inc() print(foo()) print(foo())
處理遞歸問題: def fib(): x = 0 y = 1 while True: yield y x, y = y, x+y foo = fib() for _ in range(5): print(next(foo)) for _ in range(100): next(foo) print(next(foo))
協程coroutine:
生成器的高級用法;
比進程、線程輕量級;
是在用戶空間調試函數的一種實現;
python3 asyncio就是協程實現,已經加入到標準庫;
python 3.5 使用async、await關鍵字直接原生支持協程;
協程調試器實現思路:
有2個生成器A、B
next(A)後,A執行到了yield語句暫停,而後去執行next(B),B執行到yield語句也暫停,
而後再次調用next(A),再調用next(B),周而復始,就實現了調試的效果;
能夠引入調試的策略來實現切換的方式;
協程是一種非搶佔式調試;
yield from
yield from是python3.3出現的新的語法;
yield from iterable 是 for item in iterable: yield item 形式的語法糖;
def inc(): for x in range(10): yield x foo = inc() print(next(foo)) print(next(foo))
等價於下面的代碼
def inc(): yield from range(10) foo = inc() print(next(foo)) print(next(foo))
還能夠 從可迭代對象中一個個拿元素
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))