Python函式生成器原理及使用詳解

2022-09-26 18:15:10 字數 2019 閱讀 1456

1.python函式執行原理

import inspect

frame = none

def foo():

bar()

def bar():

global frame

frame = inspect.currentframe()

pass

# python直譯器 python.exe 會用乙個叫做pyeval_evalframeex(c語言函式)去執行foo函式,首先會建立乙個棧幀(stack frame),

"""python在執行前會編譯成位元組碼物件

當foo呼叫bar函式進,又會建立乙個棧幀,

關鍵是所有的棧幀都是分配在堆記憶體, 堆記憶體有個特點,不手動釋放,就會一直存在

這就決定了棧幀可以獨立於呼叫者存在.

"""# import dis

# print(dis.dis(foo)) # 檢視foo函式的位元組碼

foo() #先呼叫一下foo函式 ,這個frame就有值.

print(frame.f_code.co_name) # bar 檢視這個棧幀, bar 所以還是可以拿到bar的棧幀,然後就可以呼叫bar函式

caller_frame = frame.f_back # 當程式設計客棧前frame棧幀的呼叫者的棧幀

print(caller_frame.f_code.co_name) # foo , 也可以拿到bar函式的棧幀

python中函式的呼叫就是建立棧幀的過程,而這些建立的棧幀都是存放在堆上面,不釋放就永久存在,所以我們拿到每個函式對應的棧幀,就可以呼叫這個函式.

j**a就不行了,函式執行完畢,直接彈棧完蛋.

2.生成器執行原理

測試**

def gen_fun():

yield 1

name = 'admin'

yield 2

gender = 'male'

return 3

看看測試**對應的位元組碼檔案

0 load_const 1 (1)

yield_value

pop_top

6 load_const 2 ('admin')

store_fast 0 (name)

10 load_const 3 (2)

yield_value

pop_top

16 load_const 4 ('male')

store_fast 1 (gender)

20 load_const 5 (3)

return_value

none

測試gi_frame程式設計客棧

# 在沒有執行生成器時

print(gen.gi_frame.f_lasti) # -1 ,在沒有呼叫next方法迭代時,f_lasti 等於-1, 表示還沒開始呢

print(gen.gi_frame.f_locals) # {}

# 執行第一行

next(gen)

print(gen.gi_frame.f_lasti) # 2 # 執行一行next後,**停在了第二行,看上面位元組碼檔案

print(gen.gi_frame.f_locals) # {}

# 再執行一次

next(gen)

程式設計客棧print(gen.gi_frame.f_lasti) # 12 # 又執行一次next之後,程式停在了12行

print(gen.gi_fra程式設計客棧me.f_locals) #

由上面的測試**可以知道,在生成器的gi_frame物件中維護著兩個重要的屬性f_lasti和f_locals.

f_lasti記錄著當前**執行到哪一行了(注意這裡的那一行是指編譯之後的位元組碼檔案)

f_locals維護著當前生成器中的屬性字段

有了這兩個屬性,生成器就知道下一次next從哪兒開始執行了....

本文標題: python函式生成器原理及使用詳解

本文位址:

python生成器函式 Python 生成器函式

一 生成器 生成器指的是生成器物件,可由生成器表示式得到,也可使用 yield 關鍵字得到乙個生成器函式,呼叫這個函式得到乙個生成器物件 生成器物件,是乙個可迭代物件,是乙個迭代器 生成器物件,是延遲計算 惰性求值的 1.1 生成器函式 函式體重包含 yield 語句的函式,就是生成器函式,呼叫後返...

python 生成器函式

python 函式的定義體中有 yield 關鍵字,該函式就是生成器函式。呼叫生成器函式時,會返回乙個生成器物件。生成器函式的定義體執行完畢後,生成器物件會丟擲stopiteration 異常。def gen a print start yield 1 print starting yield 2 ...

python函式 生成器

1.生成器 是乙個特殊的迭代器 迭代的抽象層級更高 所以,擁有迭代器的特性,惰性計算資料,節省記憶體。能夠記錄下狀態,並通過next 函式,訪問下乙個狀態。具備可迭代性。但是,如果打造乙個自己的迭代器,比較複雜,需要實現很多方法 在後續的面相物件程式設計中會講解 所以,就有乙個更加優雅的方式 生成器...