day12 裝飾器的進階
阿新 • • 發佈:2018-12-15
1裝飾器
#裝飾器的進階 #functools.wraps #帶引數的裝飾器 #多個裝飾器裝飾同一個函式 #裝飾器: #本質:閉包函式 #原則:開放封閉 #作用:不改變原函式的呼叫方式的情況下 在函式的前後新增功能 #裝飾器 def wrapper(func): def inner(*args,**kwargs): print('在被裝飾的函式執行之前要做的事') ret=func(*args,**kwargs) print('在被裝飾的函式執行之後要做的事') returnret return inner @wrapper def holiday(day): print("全體放假%s天" % day) return "很開心" print(holiday(3)) <<< 在被裝飾的函式執行之前要做的事 全體放假3天 在被裝飾的函式執行之後要做的事 很開心
*的聚合打散
#接收的時候聚合 執行的時候打散 def outer(*args): print(args) print(*args) def inner(*args): print("inner:",args) inner(*args) outer(1,2,3,4)#==outer(*[1,2,3,4])==outer(*(1,2,3,4)) (1, 2, 3, 4) 1 2 3 4 inner: (1, 2, 3, 4)
2.完美裝飾器
# 2 完美裝飾器 from functools import wraps def wrapper(func): @wraps(func) def inner(*args,**kwargs): print('在被裝飾的函式執行之前要做的事') ret=func(*args,**kwargs) print('在被裝飾的函式執行之後要做的事') return ret return inner @wrapper def holiday(day): '''這是一個放假的通知''' print("全體放假%s天" % day) return "很開心" print(holiday(3)) print(holiday.__name__) #列印函式的名字 print(holiday.__doc__) #列印函式的字串註釋 <<< 在被裝飾的函式執行之前要做的事 全體放假3天 在被裝飾的函式執行之後要做的事 很開心 holiday 這是一個放假的通知
def wahaha(): ''' 一個列印娃哈哈的函式 ''' print('wahha') print(wahaha.__name__) #檢視字串格式的函式名 print(wahaha.__doc__) #document 檢視字串格式的註釋 wahaha() <<< wahaha 一個列印娃哈哈的函式 wahha
3.作業
#1.編寫一個裝飾器 為多個函式加上認證功能(使用者的賬號密碼來源於檔案) #要求登陸成功一次 後續的函式都無需再輸入使用者名稱和密碼 FLAG=False def login(func): def inner(*args,**kwargs): global FLAG if FLAG: ret=func(*args,**kwargs) return ret else: username=input('username:') password=input('password:') if username=='hhh'and password=='123': FLAG=True ret = func(*args, **kwargs) return ret else: print('登入失敗') return inner @login def shoplist(): print('增加一件物品') @login def shoplist_remove(): print('刪除一件物品') shoplist() shoplist_remove() <<< username:hhh password:123 增加一件物品 刪除一件物品
#2 編寫裝飾器 為多個函式加上記錄呼叫功能 要求每次呼叫函式都將被呼叫的函式名稱寫入檔案 def log(func): def inner(*args,**kwargs): with open('log','a',encoding='utf-8')as f: f.write(func.__name__+'\n') ret=func(*args,**kwargs) return ret return inner @log def shoplist(): print('增加一件物品') @log def shoplist_remove(): print('刪除一件物品') return 'shanchu' shoplist_remove() shoplist() # shoplist_remove() print(shoplist_remove()) <<< 刪除一件物品 增加一件物品 刪除一件物品 shanchu
#1.編寫下載網頁內容的函式 要求功能是:使用者傳入一個人url,函式返回下載頁面的結果 #2.為題目1編寫裝飾器 實現快取網頁內容的功能: #具體:實現下載的頁面放入檔案中,如果檔案內有值(檔案大小不為0),就優先從檔案中讀取網頁內容 #否則就去下載存到檔案中 # import os from urllib.request import urlopen def cache(func): def inner(*args,**kwargs): if os.path.getsize('web_cache'): with open('web_cache','rb') as f: return f.read() ret=func(*args,**kwargs) with open('web_cache','wb')as f: f.write(b'****'+ret) return ret return inner @cache def get(url): code=urlopen(url).read() return code ret=get('https://www.baidu.com/') print(ret) ret1=get('https://www.baidu.com/') print(ret1) ret=get('https://ilovefishc.com/html5/') print(ret) <<< b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>' b'****<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>' b'****<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'
4.裝飾器的進階
1.帶引數的裝飾器
#4 裝飾器進階 #1 帶引數的裝飾器 #500個函式 import time FLAGE=False def timmer_out(flag): def timmer_out(func): def inner(*args,**kwargs): if flag: start=time.time() ret=func(*args,**kwargs) end=time.time() print(end-start) return ret else: ret = func(*args, **kwargs) return ret return inner return timmer_out @timmer_out(FLAGE) def wahaha(): time.sleep(1) print("wahahaha") @timmer_out(' ') def er(): time.sleep(1) print("222222") wahaha() er() <<< wahahaha 222222 1.0006272792816162
2.多個裝飾器裝飾同一個函式
#2 多個裝飾器裝飾一個函式 def wrapper1(func): def inner(*args,**kwargs): print("wrapper1 before func") ret=func(*args,**kwargs) print("wrapper1 after func") return ret return inner def wrapper2(func): def inner(*args,**kwargs): print("wrapper2 before func") ret=func(*args,**kwargs) print("wrapper2 after func") return ret return inner def wrapper3(func): def inner(*args,**kwargs): print("wrapper3 before func") ret=func(*args,**kwargs) print("wrapper3 after func") return ret return inner @wrapper1 @wrapper2 @wrapper3 def f(): print('in f') return "hhh" print(f()) <<< wrapper1 before func wrapper2 before func wrapper3 before func in f wrapper3 after func wrapper2 after func wrapper1 after func hhh