Python中對延遲提供了友好的支持:即它提供了在需要的時候才產生結果的工具,而不是立即產生結果。下面介紹的函數生成器就是這種工具之一。
1:生成器函數的定義
定義:使用常規的def語句進行編寫,但是使用yield語句一次返回一個結果集,在每次結果產生之間掛起和恢復它們的狀態。
# 常規函數def func1(): print('hello ') return 'ixusy88' ret = func1()print(ret) '''結果:hello ixusy88''' print("*"*30)# 生成器函數,把常規函數中的return替換為yielddef func2(): print('hello ') yield 'ixusy88' ret = func2() # 並沒有執行函數,而是返回一個生成器對象print(ret)'''結果:'''
2:生成器函數的本質
生成器函數本質就是一個迭代器:函數中如果包含一條yield語句,那麼Python就會將它編譯為生成器,這個函數不再是普通函數,而是作為返回支持迭代協議的對象的函數,這個函數返回的對象會自動創建名為__next__的方法接口。
"""yield語句會掛起該函數並向調用者傳回一個值,同時會保留足夠的狀態使函數能從它離開的地方繼續執行,當繼續時,函數在上一個yield傳回後立即繼續執行。"""def func1(N): for i in range(N): yield i**2 ret = func1(3) # 只要函數func1中有yield語句,就會返回一個支持迭代協議的對象print(ret)print('__iter__' in dir(ret))print('__next__' in dir(ret)) """輸出結果:TrueTrue"""print("*"*30) # ret 是一個支持迭代協議的對象,可以通過手工進行訪問 print(ret.__next__())print(ret.__next__())print(ret.__next__())print(ret.__next__()) # """014Traceback (most recent call last): File "D:\python\生成器函數.py", line 53, in print(ret.__next__()) # StopIterationStopIteration""" print("*"*30)ret = func1(5) # ret 是一個支持迭代協議的對象,可以使用for循環來遍歷for item in ret: print(item)"""014916"""
3:小示例
# 斐波那契函數# def Fibonacci(N): a,b,max_cnt = 0,1,N while b a,b = b,a+b yield a print('*'*30)fib = Fibonacci(5)print(fib) for x in fib: print(x) '''輸出結果:11235'''print('*'*30) # 手工訪問fib = Fibonacci(5)print(fib.__next__())print(fib.__next__())print(fib.__next__())print(fib.__next__())print(fib.__next__())print(fib.__next__()) '''結果:11235Traceback (most recent call last): File "D:\python\生成器函數.py", line 119, in print(fib.__next__())StopIteration'''