python-裝飾器&生成器&迭代器

 一:普通裝飾器

  • 概念:在不改變原函數內部代碼的基礎上,在函數執行以前和以後自動執行某個功能,爲已存在的對象添加某個功能
  1. 普通裝飾器編寫的格式
    def 外層函數(參數)
        def 內層函數(*args,**kwargs) 
            #函數執行以前
            data= 參數(*args,**kwags)
            #函數執行以後
            return data
        return 內層函數
  2. 用法示例:  
    def func(arg):
        def inner(*args,**kwargs):
            v = arg(*args,**kwargs)
            return v
        return inner
    
     @func   #@裝飾器的語法 : 等價於:  index = func(index)
      def index():
            print(123)
            return 666
      ret = index()
      print(ret)
    
    執行原理: 
      1. 函數從上往下執行,遇到 @func 時,執行 index = func(index),參數 arg = index,同時將返回值 inner 函數賦值給 index ,
      2. 遇到 index()時,此時就是 inner(),執行 inner 函數
      3. 執行 inner 函數,裏面的 arg(*args,**kwargs)執行,就是 index 函數執行,打印 123 ,同時將 index 的返回值 666 賦值給 v : v = 666 
      4. 繼續執行 inner 函數, inner 函數的返回值是 v , 執行 inner 函數的是 ret = index() , 因此 ret = v = 666

     

  3. 應用示例
    #示例:計算函數執行時間
    import time
    def base(func):
        def inner(*args,**kwargs):
            start_time = time.time()  --->#函數執行以前
            v= func(*args,**kwargs)
            end_tme = time.time()  ---->#函數執行以後
            print(end_time-start_time)
            return v
        return inner
    
    @base
    def func1():
        time.sleep(2)  # 函數執行延緩2秒
        print(123)
        
    @base
    def func2():
        time.sleep(1)
        print(456)
  •  關於返回值
    def base(func):
        def inner(*args,**kwargs):
            data = func(*args,**kwargs)
            return data
        return inner 
                           
    @base
    def index():
        print(123)
        return 666
    v1 =index()
    print(v1)
    #func函數帶括號,執行index函數,先打印'123',先將666返回給data,data再返回給v1   
  •  關於先後
    def base(func):
        def inner(*args,**kwargs)
            print('函數調用以前')
            data = func(*args,**kwargs)   #執行原函數並獲取返回值
            print('調用原函數以後')
            return data
        return inner
    @base
    def index()
        print(123)
    index()

 二:帶參數的裝飾器

  • 基本格式
    def base(counter):
        def wrapper(func):
            def inner(*args,**kwargs):
                data = func(*args,**kwargs) # 執行原函數並獲取返回值
                return data
            return inner 
        return wrapper 
    @base(9)   
    def index():
        pass
    
    # 先執行base函數,而後將返回值wrapper返回,變成不帶參數的裝飾器 
    # counter 參數在裝飾器內部任意位置都能被調用 

     

  •  用法示例
    #寫一個帶參數的函,實現:參數是多少,被裝飾的函數就要執行多少次,返回最後一次執行的結果
    
    def base(counter):
        def wrapper(func):
            def inner(*args,**kwargs):
                for i in range(counter):
                    data = func(*args,**kwargs) # 執行原函數並獲取返回值
                return data
            return inner
        return wrapper
    
    @base(5)
    def index():
        return '好難啊'
    v = index()
    print(v) 

 三:生成器 (函數的變異)

  • 概念:函數中若是存在yield,那麼該函數就是一個生成器函數,調用生成器函數,會返回一個生成器,生成器只有被for循環時,生成器內部代碼纔會執行,每次循環都會獲取yield返回的值
  • 獲取生成器的三種方式
    • 生成器函數
    • 生成器表達式
    • python內部提供的一些
  • 生成器的本質就是迭代器
    • 惟一區別: 生成器是咱們本身用python代碼構建的數據結構,迭代器都是提供的或者是轉化得來的
  •  生成器函數 : 內部是否包含yield
    def func():
        print('F1')
        yield 1
        print('F2')
        yield 2
        print('F3')
    #函數內部代碼不會執行,返回一個生成器對象
    v1 = func()
    #生成器能夠被for 循環,一旦開始循環函數內部代碼就開始執行
    for item in v1:
        print(item)
    #  F1  1  F2  2  F3  
  •  特殊的迭代對象
    def func():
        yield 1
    
    v = func()
    result = v.__iter__()
    print(result) 

 四:迭代器

  • 概念:對某種對象(str/lsit/tuple/dict/set類建立的對象)中的元素進行逐一獲取,表象:具備__nest__方法且每次調用都獲取可迭代對象中的元素
  • 優勢 : 節省內存,惰性機制
  • 缺點 : 不直觀,速度相對慢,操做方法單一,不走回頭路
  •  列表轉換成迭代器
    • v1 = iter([1,2,3,4])python

    • v2 = [1,2,3,4].__iter__()數據結構

  •  迭代器想要獲取每一個元素 : 反覆調用val = v1.__next__()
    v1 = "alex"
    v2 = iter(v1)
    while True:
         try:
            val = v2.__next__()
            print(val)
         except StopIterationas e:
            break

     

  •  直到報錯:stoplteration錯誤,表示迭代已經完畢
  •  如何判斷一個對象是不是迭代器 : 內部是否有__next__方法
  •  for 循環
    v1 = [11,22,33,44]
    
    # 1.內部會將v1轉換成迭代器
    # 2.內部反覆執行 迭代器.__next__()
    # 3.取完不報錯
    for item in v1:
        print(item) 
  •  可迭代對象
    • 內部具備_iter__方法且返回一個迭代器app

    • 能夠被for 循環函數

相關文章
相關標籤/搜索