6、迭代器、生成器和裝飾器

1.迭代器

  • 定義函數

    能被next()函數進行調用且不斷返回下一個值的對象。其內置方法中包含__iter__(返回迭代器自己)和__next__(返回容器的下一個元素)。code

  • 特徵對象

    迭代器會生成惰性序列,它經過計算把值依次的返回,一邊循環一邊計算,而不是一次性獲得全部的數據。內存

  • 優勢generator

    須要數據的時候,一次取一個,能夠在很大程度上節省內容空間,而不是一次性把全部的數據存入內存中;此外,能夠遍歷無限量的數據。string

  • 建立it

    使用iter()函數來建立。io

    string = iter('abcd')
    print(next(string))
    print(next(string))
    print(next(string))
    print(next(string))
    # 遍歷完成以後繼調用
    print(next(string))
    
    # 輸出結果
    StopIteration
    a
    b
    c
    d
    
    # 注意:當遍歷完序列時,會引起一個StopIteration異常。使用for循環能夠規避整個問題(for循環的底層使用了next方法)。
    string = iter('abcd')
    for item in string:
        print(item)
    # 輸出結果
    a
    b
    c
    d

2. 生成器

  • 定義for循環

    包含了yield語句的函數。

  • 特徵

    執行生成器函數時,其內部代碼不執行,而是返回一個生成器對象(特殊的迭代器)。生成器能夠暫停函數並返回一箇中間結果(遇到yield本次循環就終止,並返回yield後的值),能夠被for循環或者用next函數逐個取值。

  • 格式

    # 格式一
    def fun():
        print('第一次執行')
        yield 1
        print('第二次執行')
        yield 2
        print('第三次執行')
        yield 3
    
    result = fun()
    print(result, type(result))
    for i in result:
        print(i)
    
    
    # 格式二
    def fun():
        print('第一次執行')
        yield 1
        print('第二次執行')
        yield 2
        print('第三次執行')
        yield 3
    
    result = fun()
    print(next(result))
    print(next(result))
    print(next(result))
    
    
    # 輸出結果
    <generator object fun at 0x000001A203DD5A20> <class 'generator'>
    第一次執行
    1
    第二次執行
    2
    第三次執行
    3
  • 注意

    生成器中不能包含return語句,遇到return語句則會結束生成器。

    def fun():
        print('第一次執行')
        yield 1
        print('第二次執行')
        yield 2
        return 123
        print('第三次執行')
        yield 3
    
    for i in fun():
        print(i)
    
    # 輸出結果
    第一次執行
    1
    第二次執行
    2
  • 生成器推導式

    result = (lambda: i ** 2 for i in range(1, 5))
    print(type(result))
    for i in result:
        print(i())
    
    # 輸出結果
    <class 'generator'>
    1
    4
    9
    16
    
    
    # 對比列表推導式
    result = [lambda: i ** 2 for i in range(1, 5)]
    print(type(result))
    for i in result:
        print(i())
    
    # 輸出結果
    <class 'list'>
    16
    16
    16
    16

3. 裝飾器

  • 定義

    在不改變原函數內部代碼的基礎上,在函數執行以前和以後自動執行某個功能。

  • 裝飾器編寫格式

    def 外層函數(傳入參數):
        def 內層函數(*args, **kwargs):
            result = 傳入參數(*args, **kwargs)
            return result
        return 內層函數
  • 裝飾器應用格式

    @外層函數
    def index():
        pass
    
    index()
  • 做用

    # 和index函自身相比,使用裝飾器以後,執行index函數能夠在原函數的基礎上多執行print('執行原函數前')和print('執行原函數後')兩條語句,此處是以最簡單的方式來進行說明,徹底能夠根據需求將這兩個語句換成功能更復雜的語句塊。
    
    def 外層函數(傳入參數):
        def 內層函數(*args, **kwargs):
            print('執行原函數前')
            result = 傳入參數(*args, **kwargs) # 執行原函數並返回值
            print('執行原函數後')
            return result
        return 內層函數
    
    @外層函數
    def index():
        pass
    
    index()
  • 例子

    def fun(arg):
        def inner():
            print('執行函數前添加的功能:', 1)
            v = arg()
            print('執行函數後添加的功能:', 3)
            return v
        return inner
    
    # 第一步:執行fun函數並將下面的函數做爲參數傳遞,至關於:fun(index)
    # 第二步:將fun的返回值從新賦值給下面的函數名,至關於:index = fun(index)
    @fun
    def index():
        print('函數本身的功能:', 2)
        return 666
    
    index()
    
    # 輸出結果爲
    執行函數前添加的功能: 1
    函數本身的功能: 2
    執行函數後添加的功能: 3
    
    # 若沒有@fun語句(沒有使用裝飾器),輸出結果爲
    函數本身的功能: 2
  • 帶參數的裝飾器

    # 能夠用於連續屢次重複執行函數
    def with_parameter(count):
        def outer(arg):
            def inner():
                for i in range(count):
                    print('\n第%d次執行' % (i + 1))
                    print('執行函數前添加的功能:', 1)
                    v = arg()
                    print('執行函數後添加的功能:', 3)
                return v
            return inner
        return outer
    
    # 至關於:index = with_parameter(3)(index)
    @with_parameter(3)
    def index():
        print('函數本身的功能:', 2)
        return 666
    
    result = index()
    print('\n函數最後的返回結果:', result)
    
    # 輸出結果
    
    第1次執行
    執行函數前添加的功能: 1
    函數本身的功能: 2
    執行函數後添加的功能: 3
    
    第2次執行
    執行函數前添加的功能: 1
    函數本身的功能: 2
    執行函數後添加的功能: 3
    
    第3次執行
    執行函數前添加的功能: 1
    函數本身的功能: 2
    執行函數後添加的功能: 3
    
    函數最後的返回結果: 666
相關文章
相關標籤/搜索