今日總結——閉包和裝飾器
阿新 • • 發佈:2022-03-18
今日內容總結
一、閉包函式
二、閉包函式的實際應用
三、裝飾器簡介
四、簡易版本裝飾器
五、進階版本裝飾器
六、完整版本裝飾器
七、裝飾器模板(很重要)
八、裝飾器語法糖
九、裝飾器修復技術
一、閉包函式
# 閉包函式的兩大特徵 1、閉:定義在函式內部的函式 2、包:內部函式使用了外層函式名稱空間中的名字 eg: def outer(): x = 111 def inner(): print('form outer>>>inner',x) return inner x = 222 # 結果和這個x = 222沒有關係 res = outer() res() # 111
二、閉包函式實際應用
# 閉包函式是給函式傳參的另外一種方式 函式體傳參的方式: 1、形參: def index(username): print(username) 函式體程式碼需要什麼就可以在形參中寫什麼 index('owen') 2、閉包 def outer(): username = 'owen' def index(): print(username) return index res = outer() res() # owen #當這個閉包裡只寫了Owen,那就會一直使用owen def outer(username): def index(): print(username) return index res = outer('mary') # 形參username與值mary臨時繫結到outer區域性名稱中 res() # mary res1 = outer('owen')# 形參username與值owen臨時繫結到outer區域性名稱空間裡面 res1() # owen # 想要修改引數,就重新定義一個值,進行重新繫結
三、裝飾器簡介
裝飾器的本質: 例如給函式index裝飾 在不改變index原有的'呼叫方式'和'內部程式碼'的情況下給index新增新的功能 裝飾器的原則: """對外擴充套件開放,對修改封閉""" import time(呼叫模組) print(time.time()) # 1647589902.705415 # 獲取的數字就是時間戳:1970年1月1日0時0分0秒距離剛剛程式碼執行間隔的秒數 time.sleep(3) # 讓程式原地休眠三秒 print('hello world') print(time.time()) # hello world # 1647590604.362981
- 統一函式的執行時間
import time
def index():
time.sleep(3)
print('from index')
start_time = time.time() # 函式執行之前獲取的時間節戳
index()
end_time = time.time() # 函式執行之後獲取一個時間戳
print(end_time - start_time) # 用第二個時間戳減第一個時間戳,結果就是函式的執行時間
四、簡易版本裝飾器
'''給index函式增加了一個統計執行時間的功能'''
def index():
time.sleep(1)
print('from index')
start_time = time.time() # 函式執行之前獲取一個時間戳
index()
end_time = time.time() # 函式執行之後獲取一個時間戳
print(end_time - start_time) # 兩個時間戳的差值就是函式的執行時間
# 這個只能給一個函式增加功能
import time
def index():
time.sleep(1)
print('from index')
def home():
time.sleep(3)
print('from home')
print(home)
def outer(func):
def get_time():
start_time = time.time() # 函式執行之前獲取一個時間戳
func() # 呼叫了真正的index函式
end_time = time.time() # 函式執行之後獲取一個時間戳
print(end_time - start_time) # 兩個時間戳的差值就是函式的執行時間
return get_time
home = outer(home) # 狸貓換太子
home()
print(home)
五、進階版本裝飾器
# 解決的是引數問題
def out (func_name):
def get_time(*args, **kwargs):
start_time = time.time() # 開始獲取一個時間
func_name(*args, **kwargs)
end_time = time.time() # 結束獲取一個時間
print(end_time - start_time)
return get_time
# 這個主要可以改變引數,引數的型別都可以
六、完整版裝飾器
# 解決的是返回值問題
import time
def index(username):
time.sleep(3)
return username
def outer(func_name):
def get_time(*args, **kwargs): # 可變長形參,什麼資料型別都可以
start_time = time.time()
res = func_name(*args, **kwargs) # 執行真正的index函式
end_time = time.time()
print(end_time - start_time)
return res # 返回原函式的值,沒有的時候返回的是none
return get_time
index = outer(index)
res = index('起飛')
print(res)
七、裝飾器模板
# 兄弟們,這才是關鍵
def outer(func_name): # func_name用於接收被裝飾的物件(函式)
def inner(*args, **kwargs):
print('執行被裝飾函式之前 可以做的額外操作')
res = func_name(*args, **kwargs) # 執行真正的被裝飾函式
print('執行被裝飾函式之後 可以做的額外操作')
return res # 返回真正函式的返回值
return inner
八、裝飾器語法糖
# 語法糖內部原理
1、使用時最好緊跟在被裝飾物件上面
2、語法糖會自動將下面緊挨著的函式名床給@後面的函式呼叫
# 先定義一個outer函式
def outer(func_name):
def inner(*args, **kwargs):
print('執行函式之前的操作')
res = func_name(*args, **kwargs)
# 額外操作
return res
return inner
# 使用outer直接@加outer
@outer # 等價於 index = outer(index)
def index(*args, **kwargs):
print('from index')
print(index)
@outer # 等價於 home = outer(home)
def home(*args,**kwargs):
print('from home')
print(home)
九、裝飾器修復技術
from functools import wraps # 固定搭配
def outer(func_name):
@wraps(func_name) # wraps模組warps關鍵字可以把真函式的屬性提取出來,賦值給裝飾器,達到以假亂真的地步
def inner(*args, **kwargs):
print('執行被裝飾物件之前可以做的操作')
res = func_name(*args, **kwargs)
return res
return inner
@outer
def home():
'''這是函式的註釋'''
print('from home')
home()
print(home)
help(home)
# 結果為
from home
<function home at 0x00000249C8FDFCA0>
Help on function home in module __main__: