Python產生器、裝飾器

來源:互聯網
上載者:User

標籤:mat   傳回值   一個   form   修改   int   lis   核心   開始時間   

## 產生器
  - 產生器是用來建立Python序列的一個對象
  - 通常產生器是為迭代器產生資料的
  - 例如range()函數就是一個產生器
  - 每次迭代產生器時,它都會記錄上一次調用的位置,並返回下一個值,這使程式不需要建立和儲存完整的序列

## 產生器函數
  - 產生器函數與普通函數類似,但它的傳回值使用yield語句,而不是return

 1 def my_range(start=0, last=10, step=1): 2     number = start 3     while number < last: 4         yield number 5         number += step 6      7 my_range     # 是一個普通函數 8 # <function my_range at 0x7efe3dbf2e18> 9 10 my_range()   # 返回一個產生器對象11 # <generator object my_range at 0x7efe3daac360>12 13 list(my_range(1, 10))14 # [1, 2, 3, 4, 5, 6, 7, 8, 9]          

 

## 裝飾器

  - 裝飾器的作用在於在不改變原有代碼結構的前提下,對原有代碼的功能進行補充擴充
  - 裝飾器的本質上是接受函數為參數的高階函數,它把一個函數作為參數輸入並且返回一個功能拓展後的新函數

 

 1 # 裝飾器函數,為函數添加兩條語句 2 def deco(fn): 3     def new_func(*args):  # 內建函式的參數需要與傳入的fn的參數相同 4         print("執行函數:{0}".format(fn.__name__)) 5         result = fn(*args) 6         print("函數執行結果:{0}".format(result)) 7         return result 8     return new_func 9 10 11 @deco    # 使用@裝飾函數名,使用裝飾器之後,add實際上已經指向了doco函數返回的新函數12 def add(*args):13     print("我是核心代碼,可不能改動我")14     result = 015     for n in args:16         result += n17     return result18 19 20 add(1, 2, 3, 4)21 """22 執行結果:23     執行函數:add24     我是核心代碼,可不能改動我25     函數執行結果:1026 """

    

    - 一個函數可以有多個裝飾器

    - 最靠近函數的裝飾器會先執行,然後一次向上執行裝飾器

 1 def count_param(fn): 2     def new_func(*args): 3         amount = len(args) 4         fn(*args) 5         print("參數個數為:{0}".format(amount)) 6         return amount 7     return new_func 8  9 10 @count_param11 @deco12 def add(*args):13     print("我是核心代碼,可不能改動我")14     result = 015     for n in args:16         result += n17     return result18 19 20 add(1, 2, 3, 4)21 """22 執行結果:23     執行函數:add24     我是核心代碼,可不能改動我25     函數執行結果:1026     參數個數為:427 """

 

    - 如果decorator本身需要傳入參數,那就需要編寫一個返回decorator的高階函數

 1 import time 2  3  4 def log(now_time): 5     def deco(fn): 6         def new_func(*args, **kwargs): 7             print(now_time) 8             return fn(*args, **kwargs) 9         return new_func10     return deco11 12 13 @log(time.asctime(time.localtime(time.time())))14 def add(*args):15     print("我是核心代碼,可不能改動我")16     result = 017     for n in args:18         result += n19     return result20 21 22 add(1, 2, 3, 4)23 """24 執行結果:25     函數開始時間:Sun Jul  1 15:30:14 201826     我是核心代碼,可不能改動我27 """

 

  - 此時列印add函數的__name__屬性探索:

print("核心函數名:{0}".format(add.__name__))"""輸出:    核心函數名:new_func"""

  

  - 這表明雖然裝飾器表面上並沒有改變核心函數的內容,但實際上還是對核心函數的屬性進行了修改,所以還需要將核心函數的__name__屬性複製到新函數

 1 import time 2  3  4 def log(now_time): 5     def deco(fn): 6         def new_func(*args, **kwargs): 7             # 將原函數的__name__屬性複製到新函數 8             new_func.__name__ = fn.__name__ 9             print(now_time)10             return fn(*args, **kwargs)11         return new_func12     return deco13 14 15 @log(time.asctime(time.localtime(time.time())))16 def add(*args):17     print("我是核心代碼,可不能改動我")18     result = 019     for n in args:20         result += n21     return result22 23 24 add(1, 2, 3, 4)25 print("核心函數名:{0}".format(add.__name__))26 """27 執行結果:28     Sun Jul  1 15:43:00 201829     我是核心代碼,可不能改動我30     核心函數名:add31 """    

 

  - 在functools裡面有一個專門的函數處理這個問題

 1 import time 2 import functools 3  4  5 def log(now_time): 6     def deco(fn): 7         @functools.wraps(fn)      # 在新的函數上添加裝飾器,修改新函數的__name__屬性 8         def new_func(*args, **kwargs): 9             print(now_time)10             return fn(*args, **kwargs)11         return new_func12     return deco13 14 15 @log(time.asctime(time.localtime(time.time())))16 def add(*args):17     print("我是核心代碼,可不能改動我")18     result = 019     for n in args:20         result += n21     return result22 23 24 add(1, 2, 3, 4)25 print("核心函數名:{0}".format(add.__name__))26 ”“”27 執行結果:28     Sun Jul  1 15:48:10 201829     我是核心代碼,可不能改動我30     核心函數名:add31 “”“

 

 

本文參考:

  [美]Bill Lubanovic 《Python語言及其應用》
  https://www.liaoxuefeng.com 廖雪峰的官方網站 

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.