#裝飾器的進階 #functools.wraps #帶參數的裝飾器 #多個裝飾器裝飾同一個函數 #裝飾器: #本質:閉包函數 #原則:開放封閉 #做用:不改變原函數的調用方式的狀況下 在函數的先後添加功能 #裝飾器 def wrapper(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)) <<< 在被裝飾的函數執行以前要作的事 全體放假3天 在被裝飾的函數執行以後要作的事 很開心
*的聚合打散html
#接收的時候聚合 執行的時候打散 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 完美裝飾器 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
#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 帶參數的裝飾器 #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 多個裝飾器裝飾一個函數 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