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

  • 2020 年 1 月 16 日
  • 筆記

 一:普通裝飾器

概念:在不改變原函數內部程式碼的基礎上,在函數執行之前和之後自動執行某個功能,為已存在的對象添加某個功能

def 外層函數(參數)      def 內層函數(*args,**kwargs)          #函數執行之前          data= 參數(*args,**kwags)          #函數執行之後          return data      return 內層函數

用法示例:  

def func(arg):      def inner():          v = arg()           return v        return inner    # 第一步:執行func函數並將下面的函數當做參數進行傳遞,  相當於:func(index)  # 第二步: 將func返回的值重新賦值給下面的函數名   index = func(index)     @func   #@裝飾器的語法    def index():          print(123)          return 666    print(index)   

應用示例

#示例:計算函數執行時間  import time  def base(func):      def inner():          start_time = time.time()  --->#函數執行之前          v= func()          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    @x1  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返回,變成不帶參數的裝飾器   

 用法示例

#寫一個帶參數的函,實現:參數是多少,被裝飾的函數就要執行多少次,返回最後一次執行的結果    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返回的值

 生成器函數 : 內部是否包含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])

v2 = [1,2,3,4].__iter__()

迭代器想要獲取每個元素 : 反覆調用val = v1.__next__()

v1 = "alex"  v2 = iter(v1)  while True:       try:          val = v2.__next__()          print(val)       except Exception as e:          break  

 直到報錯:stoplteration錯誤,表示迭代已經完畢

如何判斷一個對象是否是迭代器 : 內部是否有__next__方法

 for 循環

v1 = [11,22,33,44]    # 1.內部會將v1轉換成迭代器  # 2.內部反覆執行 迭代器.__next__()  # 3.取完不報錯  for item in v1:      print(item)   

 可迭代對象

內部具有_iter__方法且返回一個迭代器

可以被for 循環

 五;推導式

列表推導式(也叫列表生成式)

基本格式

v1 = [i for i in 可迭代對象]  v2 = [i for i in 可迭代對象 if 條件]   #條件為true才進行append  
#示例  v1 = [99 if i>5 else 66  for i in range(10)]    v2 = [lambda : 100 for i in range(10)]  result = v5[9]()  # 100    v3 = [lambda :i for i in range(10)]  result = v7[5]()  # 9    v4 = [lambda x:x*i for i in range(10)]  # 1.請問 v4 是什麼?  函數地址  # 2.請問 v4[0](2) 的結果是什麼?  18    def num():      return [lambda x:i*x for i in range(4)]  # num() -> [函數,函數,函數,函數]  print([ m(2) for m in num() ])   # [6,6,6,6]    #####篩選#####  v = [i for i in range(10) if i > 5]

 集合推導式

v1 = { i for i in 'alex' } 

 字典推導式

v1 = { 'k'+str(i):i for i in range(10) } 

 生成器推導器

def func():      for i in range(10):      yield i  v2 = func()    #或者  v2 = (i for i in range(10))   # 生成器推導式(不是元組推導式),創建了一個生成器,內部循環為執行。  for item in v2:      print(item)