Python淺析:迭代器Iterator、生成器generator、裝飾器decorator

背景:在學習如何刪除列表中的重複元素時,產生了三種方法:1、直接list(set(list(data))); 2、構造merge(data)函數,使用return關鍵字返回set集合,再使用list封裝;3、使用yield關鍵字,返回set集合,再使用list封裝,代碼很簡單,直接給出:

#method 1 :
data = [3, 3, 2, 4, 5, 3, 2, 2 , 1]
list(set(data))

>>> [1, 2, 3, 4, 5]

#method 2 :
def merge(data):
    result = set()
    for item in data:
        if item not in result:
            result.add(item)
    return result
data = [3, 3, 2, 4, 5, 3, 2, 2 , 1]
list(merge(data))

>>> [1, 2, 3, 4, 5]

#method 3 :
def merge(data):
    result = set()
    for item in data:
        if item not in result:
            yield item
            result.add(item)
data = [3, 3, 2, 4, 5, 3, 2, 2 , 1]
list(merge(data))

>>> [3, 2, 4, 5, 1]

 顯然,使用方法1和方法2給出的結果是相同的,方法3卻給出了截然不同的答案,爲此做了一下整理。

  • 知識點1:迭代器(Iterator)

定義:一個實現了iter方法的對象是可迭代的,一個實現next方法並且是可迭代的對象是迭代器。

迭代器方法:iter()函數:將可迭代對象(Iterable)轉換爲迭代器(Iterator)

  • 知識點2:生成器(generator)

生成器是一個特殊的程序,可以被用作控制循環的迭代行爲,python中生成器是迭代器的一種使用yield返回函數,每次調用yield會暫停,而可以使用next()函數和send()函數恢復生成器

生成器類似於返回值爲數組的一個函數,這個函數可以接受參數,可以被調用,但是不同於一般的函數會一次性 返回包括了所有數值的數組,生成器一次只能產生一個值,這樣消耗的內存數量將大大減小,而且允許調用函數可以很快的處理前幾個返回值,因此生成器看起來像是一個函數,但是表現得卻像是迭代器

生成器都是Iterable對象,但list, dict, str雖然是Iterable,卻不是Iterator, 調用iter()方法可轉換爲Iterator。

  • 知識點3:修飾器()

裝飾器是一個很著名的設計模式,經常被用於有切面需求的場景【函數進入和退出時需要計時,這被稱爲一個橫切面 (Aspect),這種編程方式被稱爲面向切面的編程(Aspect-Oriented Programming)】,較爲經典的有插入日誌、性能測試、事務處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,就可以抽離出大量函數中與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝飾器的作用就是爲已經存在的對象添加額外的功能。

  • 知識點4:set底層數據結構

set的去重是通過兩個函數__hash__和__eq__結合實現的。 1、當兩個變量的哈希值不相同時,就認爲這兩個變量是不同的 2、當兩個變量哈希值一樣時,調用__eq__方法,當返回值爲True時認爲這兩個變量是同一個,應該去除一個。返回False時,不去重。

因此可以看到,使用return方法和直接使用set方法封裝效果一致,理解yield關鍵字是重點。

更多細節實例參見:

1、 python 生成器和迭代器有這篇就夠了

2、理解Python中的裝飾器

3、How to make a chain of function decorators?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章