Python初探第二篇-裝飾器和迭代器,產生器

來源:互聯網
上載者:User

標籤:stop   情況下   運行時   計時   元組   import   簡潔   __iter__   載入   

一,裝飾器

  1,概念

  裝飾器就是給已有的模組添加新的功能,如登入驗證功能,已耗用時間功能等。本身可以是任意可調用對象,被裝飾者也可以是任意可調用對象。
  強調裝飾器的原則:1 不修改被裝飾對象的原始碼 2 不修改被裝飾對象的調用方式
  裝飾器的目標:在遵循1和2的前提下,為被裝飾對象添加上新功能

  2,理論基礎

  要想實現裝飾器的功能,我們需要三個理論基礎:函數閉包+函數嵌套+高階函數。我們通過為如下模組加入統計已耗用時間的裝飾器來講解如何使用

import timedef test_func():    for i in range(5):        time.sleep(0.5)

  3,推導

  首先我們知道要知道函數的已耗用時間,只需要在函數前後加上目前時間,通過差值就能計算出來。因此我們可以定義一個模組,並傳入所求的函數的函數地址,即高階函數。

  模組中包含此函數的調用和統計時間的功能

import timedef test_func():    for i in range(5):        time.sleep(0.5)def decorate(func):    start_time = time.time()    func()    end_time = time.time()    print(end_time-start_time)decorate(test_func)   #2.5s

  這樣就實現了統計時間的功能,但是卻修改了函數的調用邏輯,因此進一步思考,我們可以在裝飾器函數內定義函數,並在此函數內調用被統計函數,即函數嵌套,並返回

       代碼 如下:

import timedef test_func():    for i in range(5):        time.sleep(0.5)def decorate(func):    def count_time():        start_time = time.time()        func()        end_time = time.time()        print(end_time-start_time)    return count_timetest_func = decorate(test_func)test_func()

而python給我們提供了裝飾器文法:

import timedef decorate(func):    def count_time():        start_time = time.time()        func()        end_time=time.time()        print(end_time-start_time)    return count_time@decorate def test_func():    for i in range(5):        time.sleep(0.5)test_func()

 上面就實現了一個簡單的裝飾器,可根據需求來增加它的功能,如傳入參數,傳回值等。

 

二,迭代器

  1,概念

  迭代器(iteretor)是一種遍曆容器所有或者部分元素的方法,相當於一個複雜的指標,能夠遍曆複雜的資料結構,一個容器也應該提供它自己的迭代器。

  2,迭代器對象與可迭代對象

   迭代器對象:即對象能夠提供遍曆它的方法,像是迭代器的一種具體表現,在Python中迭代器對象能夠提供__iter__和__next__方法來得到容器中下一個元素的值。

   可迭代對象:即對象提供__iter__方法,使用該方法後得到迭代器對象,如字串,列表元組

li=[1,2,3,4,5]li=li.__iter__()  # 可迭代對象轉化成迭代器對象print(li.__next__())  # 1

  3,使用方法  

dic = {"a": 1, "e": 4, "b": 2, "c": 3, "d": 4}iter_dic = dic.__iter__()# while True:try:    print(next(iter_dic))   #"a" "e" "b".....except StopIteration:     #需要手動捕捉異常    break

  而我們可以藉助Python中強大的for迴圈機制來迴圈遍曆容器

  4,for迴圈

#基於for迴圈,我們可以完全不再依賴索引去取值了dic = {‘a‘:1,‘b‘:2,‘c‘:3}for k in dic:    print(dic[k])#for迴圈的工作原理#1:執行in後對象的dic.__iter__()方法,迭代器對象.__iter,返回對象本身。得到一個迭代器對象iter_dic#2: 執行next(iter_dic),將得到的值賦值給k,然後執行迴圈體代碼#3: 重複過程2,直到捕捉到異常StopIteration,結束迴圈

 三,產生器

  Python使用產生器能夠實現延時操作,何謂延時操作,即需要結果時就產生結果,不需要時就不產生。提供產生器對象有兩種方式:

  1,產生器函數:和常規的函數定義一樣只不過不用return,而是使用yield來返回結果。一次只返回一個結果,在每個結果中間,掛起函數狀態,以便下次繼續返回。

  2,產生器運算式:產生一個產生器對象,按需產生結果,就是迭代的時候產生具體的值。

 

    1,產生器函數  

def gensquares(n):    for i in range(n):        yield i ** 2obj = gensquares(5)print(obj)  # <generator object gensquares at 0x00000000021E55C8>print(next(obj))  # 0print(next(obj))  # 1print(next(obj))  # 4

  2,產生器運算式

li = []for i in range(5):    name = "name%d" % i    li.append(name)print(li)  # [‘name0‘, ‘name1‘, ‘name2‘, ‘name3‘, ‘name4‘]# 列表推導li = ["name%d" % i for i in range(5)]print(li)  # [‘name0‘, ‘name1‘, ‘name2‘, ‘name3‘, ‘name4‘]# 簡潔了許多# 產生器運算式gens = ("name%d" % i for i in range(5))print(gens)  # <generator object <genexpr> at 0x00000000028655C8>print(next(gens))  # name0print(next(gens))  # name1print(next(gens))  # name2
#產生器對象就是迭代器對象

     使用產生器的好處資料不會直接載入到記憶體,在資料量很大的情況下作用很大。比如使用內建函數如下

#print(sum([i for i in range(100000000)])) #提示電腦記憶體不足,程式崩潰print(sum((i for i in range(1000000000)))) #程正常運行

    注意事項:產生器對象是一種迭代器對象,它們都只能遍曆一次,而可迭代對象可以多次遍曆。

 

Python初探第二篇-裝飾器和迭代器,產生器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.