Python3_裝飾器
1、裝飾器的定義
裝飾器本質上就是一個函式,功能是為其他函式新增功能
裝飾器的原則:
- 不修改被裝飾函式的原始碼
- 不修改被裝飾函式的呼叫方式
2、裝飾器的知識儲備
先宣告一點:裝飾器=高階函式+函式巢狀+閉包
2.1、高階函式
定義:
- 函式的引數是一個函式
- 函式的返回值是一個函式
2.2、巢狀函式
定義:
- 在一個函式的內部又定義一個函式
注:在巢狀函式中外部的函式稱為外函式,在函式內部定義的函式稱為內函式
2.3、閉包
定義:
- 內函式呼叫外函式的臨時變數
- 外函式的返回值是內函式的引用
程式碼示例:
def test(a, b): def test2(): print(a + b) return test2 res = test(1, 2) res()# 相當於呼叫test2()
3、裝飾器
3.1、裝飾器的基本語法格式
通過上面已經知道了 裝飾器=高階函式+函式巢狀+閉包,下面來實現一下裝飾器
使用裝飾器統計函式test執行的時間
import time def timer(func): '計算程式執行時間的函式' def count(): start_time = time.time() func() end_time = time.time() print("執行的時間是%s" % (end_time - start_time)) return count @timer# @timer就是相當與執行了timer(test)() def test(): time.sleep(3) print("函式test執行結束")
執行時間:
函式test執行結束
執行的時間是3.0005695819854736
3.2、函式加上返回值
當我們在test函式中加上一個return返回值的時候會發現在呼叫test函式的時候並沒有返回值,原因是函式test是在裝飾器函式的內函式中執行的,在內函式中並沒有return值,修改如下:
import time def timer(func): def count(): start_time = time.time() res = func() print(res) end_time = time.time() print("執行的時間是%s" %(end_time - start_time)) return count @timer def test(): time.sleep(3) print("函式test執行結束") return "這是test的返回值" test()
3.3、函式加上引數
當對test函式加上引數的時候會發現程式碼報錯,原因是在裝飾器的內函式中我們並沒有給定形參,導致test在內函式中執行時無法接收相應的實參;修改如下:
import time def timer(func): def count(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) print(res) end_time = time.time() print("執行的時間是%s" %(end_time - start_time)) return count @timer def test(name, age): time.sleep(3) print("函式test執行結束") print("名字 【%s】,年齡【%s】" %(name, age)) return "這是test的返回值" test("xiaoming", 20)
執行結果:
函式test執行結束
名字 【xiaoming】,年齡【20】
這是test的返回值
執行的時間是3.0006966590881348
3.4、給裝飾器函式加上引數
如果需要給使用者選擇test函式是否要統計執行時間的話就要給裝飾器新增一個引數,判斷是否要統計test執行的時間;可使用閉包
情況1:需要進行運算時間的統計
import time def auth(para = True): def timer(func): def count(*args, **kwargs): if para == True: start_time = time.time() res = func(*args, **kwargs) print(res) end_time = time.time() print("執行的時間是%s" %(end_time - start_time)) else: func(*args, **kwargs) return count return timer @auth(para=True) def test(name, age): time.sleep(3) print("函式test執行結束") print("名字 【%s】,年齡【%s】" %(name, age)) return "這是test的返回值" test("xiaoming", 20)
執行結果:
函式test執行結束
名字 【xiaoming】,年齡【20】
這是test的返回值
執行的時間是3.0004258155822754
情況2:不需要進行運算時間的統計
import time def auth(para = True): def timer(func): def count(*args, **kwargs): if para == True: start_time = time.time() res = func(*args, **kwargs) print(res) end_time = time.time() print("執行的時間是%s" %(end_time - start_time)) else: func(*args, **kwargs) return count return timer @auth(para=False) def test(name, age): time.sleep(3) print("函式test執行結束") print("名字 【%s】,年齡【%s】" %(name, age)) return "這是test的返回值" test("xiaoming", 20)
執行結果:
函式test執行結束
名字 【xiaoming】,年齡【20】