1. 程式人生 > >python之裝飾器與生成器

python之裝飾器與生成器



裝飾器和生成器

裝飾器:

def hello(fn):  #1,3
   
def wrapper (): #4
       
fn()
   
return  wrapper  #5

@hello  #2
def foo():
   
print("123")
foo() #6

裝飾器執行流程如上圖所標註的那樣:

第一步:執行def  hello(fn)

第二步:執行@

hello。此句的意思為:foo = hello(foo),也就是將foo函式作為引數傳遞給hello函式,再回調

第三步:此時fn=foo

第四步:執行wrapper函式

第五步:返回整個wrapper函式

第六步:foo()=wrapper()。輸出wrapper()函式的值,此前因為foo = hello(foo),而執行hello(foo)函式,返回的結果就是wrapper整個函式,所以foo()=wrapper().

 

重點理解:

1.python中一切皆為物件,函式是第一類物件,所謂第一類物件,意思是可以用識別符號給物件命名,並且物件可以被當作資料處理,例如賦值、作為引數傳遞給函式,或者作為返回值

return 等,所以foo函式才可以作為引數去傳遞,才可以出現return wrapper.

2.foo()foo的區別,foo是函式,foo()是呼叫函式後的值,無論是把函式賦值給新的識別符號,還是把函式作為引數傳遞給新的函式,針對的都是函式物件本身,而不是函式的呼叫。foo 函式物件本身,foo()函式的呼叫。

 

生成器:

·  生成器,即生成一個容器。

·  Python中,一邊迴圈,一邊計算的機制,稱為生成器。

·  生成器可以理解為一種資料型別,這種資料型別自動實現了迭代器協議(其他資料型別需要呼叫自己的內建

iter()方法或__iter__()的內建函式),所以,生成器就是一個可迭代物件。

·  Python中,使用生成器可以很方便的支援迭代器協議

 

生成器優點:

Python使用生成器對延遲操作提供了支援,所謂延遲操作,是指在需要的時候才產生結果,而不是立即產生結果。

  • 生成器是可迭代物件;
  • 實現了延遲計算,省記憶體(按需執行);
  • 生成器本質和其他型別一樣,都是實現了迭代器協議,只不過生成器是一邊計算,一邊生成,從而節省記憶體空間,其餘的可迭代物件可沒有這個功能。

迭代器協議:生成器自動實現了迭代器協議

迭代器協議是指:物件提供next()方法,它要麼返回迭代中的下一項,要麼就引起一個StopIteration異常,以終止迭代。

可迭代物件:實現了迭代器協議的物件

協議是一種約定,可迭代物件實現迭代器協議,Python的內建工具(for迴圈、summinmax函式等)使用迭代器協議訪問物件

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時,就已經遍歷了生成器,再往下執行時,將不會有任何記錄。