生成器:
生成器值得時生成器對象,能夠由生成器表達式獲得,也能夠使用yield關鍵字獲得一個生成器函數,調用這個函數獲得一個生成器
生成器函數
函數體中包含yield語句的函數,返回生成器對象
生成器對象,是一個可迭代對象,是一個迭代器
生成器對象,是延遲計算,惰性求值
生成器示例(1,1):
def inc(c): y=(i for i in range(5))
for i in range(5): print(type(y))
yield i print(next(y))
print(type(inc)) print(next(y))
print(type(inc())
for m in x:
print(m.'*')
for m in x:
print(m,'**')
代碼(1,1)分析:
普通的函數調用fn,函數會當即執行完畢,可是生成器函數能夠使用next函數進行惰性求值
生成器數等價於生成器表達式,只不過生成器函數能夠更加的複雜
代碼(1,2):
def foo():
print('hello')
yield 'world'
print("we'a")
yield 'chinese'
print('love')
yield 'china'
print('emm')
return 'bye
代碼(1,2)分析:
在生成器函數中使用多個yield語句,執行一次後會暫停,並返回yield表達式的返回值
再次執行該生成器函數時,會向下執行到下一個yield語句
return語句依然能夠終止函數運行,可是return語句的返回值不會獲取到
return會致使沒法繼續獲取下一個值,拋出StopIteration
若是函數沒有顯示的return語句,若是生成器函數執行到結尾,同樣會拋出StopIteration異常
生成器函數總結:
包含yield語句的生成器函數生成 生成器對象的時候,生成器函數的函數體不會當即執行
next(迭代器or生成器) 會從函數的當前位置向後執行到以後碰到的第一個yield語句,會彈出值,並暫停函數的運行
再次調用函數,會重複上述的步驟
當沒有多餘的yield語句被執行時,繼續調用next()函數,會拋出StopIteration異常
生成器應用:
無限循環
def counter(): def counter():
i = 0 i=0
while True: while True:
i+=1 i+=1
yield i yeild i
def inc(c): def inc():
return next(c) c = counter()
return next(c)
c=counter() print(inc(c))
print(inc(c)) print(inc(c))
print(inc(c)) print(inc(c))
左側顯示爲1,2.右側顯示爲1,1,1
def inc():
def counter():
i=0
while True:
i+=1
yield i
c= counter()
return lamdba : next(c)
foo=inc(c)
print(foo())
print(foo())
lambda 表達式是匿名函數
return 返回的是一個匿名函數
等價於:
def inc():
def counter():
i=0
while True:
i+=1
yield i
c = counter()
return lambda : next(c)
foo= inc()
print(foo())
print(foo())
返回結果爲 1,2
協程
生成器的高級用法
比線程,進程輕量級
實在用戶空間調度函數的一種實現
協程調度器實現思路:
有2個生成器
next(A)後,A,B
next(A),A 執行到了yield 語句暫停,在執行next(B),B執行到yield語句也暫停,而後再次調用next(A),再調用next(B),周而復始,實現了調度的效果
能夠引入調度的策略來實現切換的方式
協程是一種非搶佔式調度
def ince(): def inc():
for x in range(1000): yield from range(1000):
yield x foo = inc()
print(next(foo))
foo=inc() print(next(foo))
print(next(foo)) print(next(foo))
print(next(foo))
print(next(foo))