生成器是一種快速完成迭代器功能的工具,是一種特殊的迭代器。通過在函式中,設定關鍵字yield,即為生成器函式。
def student():
yield 1
yield 2
yield 3
為什麼說生成器是一種特殊的迭代器,可以通過isinstance函式判斷。
可以看到,生成器是可迭代物件,也是迭代器物件。
同樣可以使用生成器來解決斐波那契數列的問題。
def gen_fib(index):
n,a,b = 0,0,1
while n在講生成器原理之前,我們需要先明白python函式的原理。我們的**通過直譯器python.exe來完成,一般情況下,python的底層由c語言編寫,也就是我們常說的cpython。python函式的執行需要借助由c語言編寫好的pyeval_evalframex函式,首先會建立好乙個叫做stack frame的東西。stack frame(棧幀)也是乙個物件,將**會變成位元組碼物件。同時棧幀是放在堆記憶體上的。
看到這各位看官可能會覺得有點抽象。下面以乙個具體的例子來說明。棧幀我們可以使用inspect模組來研究。inspect可以從實時的python物件中獲得我們想要的資訊。可以看到輸出結果分別為levy()和student()函式的棧幀名。
import inspect
stack_frame = none #棧幀變數
def student():
levy()
return "i am a student"
def levy():
global stack_frame #定義乙個全域性變數
stack_frame = inspect.currentframe() #獲得當前的棧幀
student() #呼叫student()函式後生成棧幀
print(stack_frame.f_code.co_name) #棧幀的名字
last_stack_frame = stack_frame.f_back #上乙個棧幀
print(last_stack_frame.f_code.co_name) #輸出上乙個棧幀的名字
通過一張圖我們很容易理清其中的關係,上面為student()函式,下面為levy()函式。
借助dis模組我們可以將python位元組碼反彙編成助記符,用於分析案例的原理。參考下圖,load_global載入函式levy(), load_const載入return的返回值"i am a student'。
import inspect,dis
stack_frame = none #棧幀變數
def student():
levy()
return "i am a student"
def levy():
global stack_frame #定義乙個全域性變數
stack_frame = inspect.currentframe() #獲得當前的棧幀
dis.dis(student) #dis模組的使用
如果理解了上面的原理的話,我們下面再來看生成器的原理分析。生成器中的堆記憶體儲存了genobject指向了幀物件和位元組碼物件。
生成器原理的示例如下,我們輸出反編譯後的助記符行號以及本地儲存變數(字典形式),通過不斷的呼叫next()函式,來順序訪問生成器函式中的物件。
def stu():
yield "hello"
student = 'levy'
yield "world"
return "i am a student"
import dis
xiaoming = stu()
dis.dis(xiaoming)
print(xiaoming.gi_frame.f_lasti)#位元組碼對應行數
print(xiaoming.gi_frame.f_locals)#本地變數字典形式
next(xiaoming)#執行下乙個
print(xiaoming.gi_frame.f_lasti)
print(xiaoming.gi_frame.f_locals)
next(xiaoming)
print(xiaoming.gi_frame.f_lasti)
print(xiaoming.gi_frame.f_locals)
-1表示生成器函式還未開始執行,儲存的變數為空{},2表示執行到第二行yield_value返回了乙個"hello"字串,同理12表示第十二行yield_value返回了乙個"world"字串。生成器的執行大致如我所說,通過惰性計算,每次返回乙個所需的值,並且能夠記住**的執行位置,可以對整個生成器的暫停和前進進行控制。
分析報告生成器,Word文件自動生成器
多特 軟體介紹 該軟體為共享軟體,如果你喜歡這個軟體,並且能為你帶來價值,請購買。軟體 為 2900元 套.乙個使用者可以部署在兩台電腦上執行。在日常工作中,你一定遇到這樣的事情,經常要在每個固定時間出乙個報告,或簡單或複雜。每次還可能要改動一些引數。報告的形式可能是文字描述,也有圖表,但格式都不固...
生成器之全景分析
yield指令,可以暫停乙個函式並返回中間結果。使用該指令的函式將儲存執行環境,並且在必要時恢復。生成器比迭代器更加強大也更加複雜,需要花點功夫好好理解貫通。看下面一段 python view plain copy defgen forx inxrange 4 tmp yield x if tmp ...
python 生成器作用 Python生成器
生成器介紹 在函式內部包含yield關鍵字,那麼該函式執行的結果是生成器,生成器就是迭代器。生成器的功能 把函式結果做成迭代器 以一種優雅的方式封裝好iter,next 提供了一種自己定義迭代器的方式。使用生成器建立乙個迭代器 def a print a yield 11 使用yield,執行後返回...