閉:封閉python
包:包裹閉包
閉包函數必須在函數內部定義app
閉包函數能夠引用外層函數的名字函數
閉包函數就是函數嵌套,函數對象,名稱空間與做用域的結合體工具
直接傳參url
def fun(x): print(x) func(1000)
經過閉包函數傳參code
def outer(num): def inner(): print(num) return inner func = outer(100)#inner地址 func()
什麼是裝飾器對象
裝飾:裝飾,修飾內存
器:工具作用域
裝飾器必需要遵循的‘開放封閉原則’
開放:對函數功能的添加是開放的
封閉:對函數功能的修改是封閉的
裝飾器的做用
在不修改被裝飾對象源代碼與調用方式的前提下,添加新的功能
被修飾對象:須要添加功能的函數
裝飾對象:添加功能函數
應用
統計時間
登陸認證
能夠解決冗餘代碼,提升代碼可擴展性
小實例結合time包
import time # 被修飾函數 def download_movie():#download_movie函數名 print('開始下載電影') time.sleep(3)#模擬下載時間 print('電影下載成功') start_time = time.time() download_movie() end_time = time.time() print(f'電影下載時間:{end_time - start_time}') >>>開始下載電影 電影下載成功 電影下載時間:3.0007519721984863 #裝飾器即裝飾函數 def time_record(func):#time_record裝飾器的函數名,func形參,用來接收實參 def inner():#內部函數名 start_time = time.time() func()#執行接收到的函數 end_time = time.time() print(f'電影下載時間:{end_time - start_time}') return inner#調用time_record這個函數返回inner的內存地址 #print(time_record(download_movie))#time_record(download_movie)是一個內存地址 download_movie = time_record(download_movie) download_movie() >>>開始下載電影 電影下載成功 電影下載時間:3.000049352645874 開始下載電影 電影下載成功 電影下載時間:3.00085186958313 #一、被修飾對象有返回值 import time def download_movie(): print('開始下載電影') time.sleep(3)#模擬下載時間 print('電影下載成功') return '小澤.mp4'#調用函數返回'小澤.mp4' def time_record(func):#func<---download_movie def inner(): start_time = time.time() res = func()#res = '小澤.mp4' # print(res)#res字符串 end_time = time.time() print(f'電影下載時間:{end_time - start_time}') return res#調用函數inner返回res # print(inner()) return inner#調用函數time_record返回inner,此時纔是地址 # print(time_record(download_movie))#inner地址 download_movie = time_record(download_movie) download_movie() >>>開始下載電影 電影下載成功 電影下載時間:3.0000083446502686 #二、被修飾對象有參數 import time def download_movie(url):#url用來接收參數 print('開始下載電影') time.sleep(3)#模擬下載時間 print('電影下載成功') return '小澤.mp4'#返回'小澤.mp4' def time_record(func):#func用來接收被修飾函數func<---download_movie def inner(url):#url接收參數 start_time = time.time() res = func(url)#func(url)<----download_movie(url) end_time = time.time() print(f'電影下載時間:{end_time - start_time}') return res#把res即(download_movie(url))---->inner return inner#(download_movie(url))---->time_record download_movie = time_record(download_movie) download_movie('https://www.jd.com/') >>>開始下載電影 電影下載成功 電影下載時間:3.0002450942993164 #三、有多個參數 import time def download_movie(*args, **kwargs): print('開始下載電影') time.sleep(3)#模擬下載時間 print('電影下載成功') return '小澤.mp4'#把'小澤.mp4' def time_rcod(func): def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print(f'電影下載時間:{end_time - start_time}') return res return inner download_movie = time_rcod(download_movie) download_movie('https://www.baidu.com/') >>>開始下載電影 電影下載成功 電影下載時間:3.000089168548584
裝飾器模板
def wrapper(func): def inner(*args,**kwargs): #添加功能 res = func(*args,**kwargs) #添加功能 return res return inner def func1(): pass func1 = wrapper(func1)#func1被修飾函數,wrapper修飾函數 func1()
裝飾器語法糖
裝飾器的語法糖是屬於裝飾器的
@:裝飾器的語法糖
注意:在使用裝飾器的語法糖時,裝飾器必須定義在被裝飾函數前
# 統計函數執行時間裝飾器 def wrapper(func): # 被裝飾對象 def inner(*args, **kwargs): # 被裝飾對象的參數 # 調用前增長新功能 start_time = time.time() # 調用被裝飾對象,並接收返回值 res = func(*args, **kwargs) # 調用後添加新功能 end_time = time.time() print(end_time - start_time) return res return inner # func函數須要執行3秒 # 無參裝飾器 # 使用裝飾器 @wrapper # wrapper(func) ---> func def func(): time.sleep(3)