python之裝飾器與生成器
裝飾器和生成器
裝飾器:
def hello(fn): #1,3
def wrapper (): #4
fn()
return wrapper #5
@hello #2
def foo():
print("123")
foo() #6
裝飾器執行流程如上圖所標註的那樣:
第一步:執行def hello(fn)。
第二步:執行@
第三步:此時fn=foo
第四步:執行wrapper函式
第五步:返回整個wrapper函式
第六步:foo()=wrapper()。輸出wrapper()函式的值,此前因為foo = hello(foo),而執行hello(foo)函式,返回的結果就是wrapper整個函式,所以foo()=wrapper().
重點理解:
1.python中一切皆為物件,函式是第一類物件,所謂第一類物件,意思是可以用識別符號給物件命名,並且物件可以被當作資料處理,例如賦值、作為引數傳遞給函式,或者作為返回值
2.foo()和foo的區別,foo是函式,foo()是呼叫函式後的值,無論是把函式賦值給新的識別符號,還是把函式作為引數傳遞給新的函式,針對的都是函式物件本身,而不是函式的呼叫。foo 函式物件本身,foo()函式的呼叫。
生成器:
· 生成器,即生成一個容器。
· 在Python中,一邊迴圈,一邊計算的機制,稱為生成器。
· 生成器可以理解為一種資料型別,這種資料型別自動實現了迭代器協議(其他資料型別需要呼叫自己的內建
· 在Python中,使用生成器可以很方便的支援迭代器協議
生成器優點:
Python使用生成器對延遲操作提供了支援,所謂延遲操作,是指在需要的時候才產生結果,而不是立即產生結果。
- 生成器是可迭代物件;
- 實現了延遲計算,省記憶體(按需執行);
- 生成器本質和其他型別一樣,都是實現了迭代器協議,只不過生成器是一邊計算,一邊生成,從而節省記憶體空間,其餘的可迭代物件可沒有這個功能。
迭代器協議:生成器自動實現了迭代器協議
迭代器協議是指:物件提供next()方法,它要麼返回迭代中的下一項,要麼就引起一個StopIteration異常,以終止迭代。
可迭代物件:實現了迭代器協議的物件
協議是一種約定,可迭代物件實現迭代器協議,Python的內建工具(for迴圈、sum、min、max函式等)使用迭代器協議訪問物件
在python中,for迴圈不僅可以遍歷列表,也可以遍歷檔案
with open ('/etc/passwd') as f: for line in f: print(line)
因為檔案物件實現了迭代器協議,for迴圈並不知道它所遍歷的是一個檔案物件,它只管使用迭代器協議訪問物件即可。
注意:生成器只能遍歷一次。
例如:
def get_province_population(filename): with open(filename) as f: for line in f: yield int (line) gen = get_province_population('data.txt') all_population = sum(gen) for population in gen: print(population/all_population)
此段程式碼執行完不會有任何輸出,因為在執行到sum時,就已經遍歷了生成器,再往下執行時,將不會有任何記錄。