1,内容回顧
# 裝飾器的進階
# functools.wraps
# 帶參數的裝飾器
# 多個裝飾器裝飾同一個函數
# 裝飾器
# 開發原則 : 開放封閉原則
# 裝飾器的作用 :在不改變原函數的調用方式的情況下,在函數的前後添加功能
# 裝飾器的本質 : 閉包函數
# def wrapper(func):
# def inner(*args,**kwargs):
# print('在被裝飾的函數執行之前做的事')
# ret = func(*args,**kwargs)
# print('在被裝飾的函數執行之後做的事')
# return ret
# return inner
#
# @wrapper #holiday = wrapper(holiday)
# def holiday(day):
# print('全體放假%s天'%day)
# return '好開心'
#
# ret = holiday(3)
# print(ret)
# 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))
2,作業
1)編寫裝飾器,為多個函數加上認證的功能(使用者的賬号密碼來源于檔案), 要求登入成功一次,後續的函數都無需再輸入使用者名和密碼
# FLAG = False
# def login(func):
# def inner(*args,**kwargs):
# global FLAG
# '''登入程式'''
# if FLAG:
# ret = func(*args, **kwargs) # func是被裝飾的函數
# return ret
# else:
# username = input('username : ')
# password = input('password : ')
# if username == 'boss_gold' and password == '22222':
# FLAG = True
# ret = func(*args,**kwargs) #func是被裝飾的函數
# return ret
# else:
# print('登入失敗')
# return inner
#
# @login
# def shoplist_add():
# print('增加一件物品')
#
# @login
# def shoplist_del():
# print('删除一件物品')
#
# shoplist_add()
# shoplist_del()
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_add():
# print('增加一件物品')
#
# @log
# def shoplist_del():
# print('删除一件物品')
# shoplist_add()
# shoplist_del()
# shoplist_del()
# shoplist_del()
# shoplist_del()
# shoplist_del()
3)進階作業:
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) #get()
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('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
3,wraps
from functools import wraps
def wrapper(func): #func = holiday
____@wraps(func)
____def inner(*args,**kwargs):
________print(‘在被裝飾的函數執行之前做的事’)
________ret = func(*args,**kwargs)
________print(‘在被裝飾的函數執行之後做的事’)
________return ret
____return inner
from functools import wraps
def wrapper(func): #func = holiday
@wraps(func)
def inner(*args,**kwargs):
print('在被裝飾的函數執行之前做的事')
ret = func(*args,**kwargs)
print('在被裝飾的函數執行之後做的事')
return ret
return inner
@wrapper #holiday = wrapper(holiday)
def holiday(day):
'''這是一個放假通知'''
print('全體放假%s天'%day)
return '好開心'
print(holiday.__name__)
print(holiday.__doc__)
ret = holiday() #inner
print(ret)
# def wahaha():
# '''
# 一個列印娃哈哈的函數
# :return:
# '''
# print('娃哈哈')
# print(wahaha.__name__) #檢視字元串格式的函數名
# print(wahaha.__doc__) #document
4,裝飾器進階
1)帶參數的裝飾器
#500個函數
# import time
# FLAGE = False
# def timmer_out(flag):
# def timmer(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
# # timmer = timmer_out(FLAGE)
# @timmer_out(FLAGE) #wahaha = timmer(wahaha)
# def wahaha():
# time.sleep(0.1)
# print('wahahahahahaha')
#
# @timmer_out(FLAGE)
# def erguotou():
# time.sleep(0.1)
# print('erguotoutoutou')
# wahaha()
# erguotou()
2)多個裝飾器裝飾一個函數(俄羅斯套娃)
def wrapper1(func):
def inner1():
print('wrapper1 ,before func')
ret = func()
print('wrapper1 ,after func')
return ret
return inner1
def wrapper2(func):
def inner2():
print('wrapper2 ,before func')
ret = func()
print('wrapper2 ,after func')
return ret
return inner2
def wrapper3(func):
def inner3():
print('wrapper3 ,before func')
ret = func()
print('wrapper3 ,after func')
return ret
return inner3
@wrapper3
@wrapper2
@wrapper1
def f():
print('in f')
return '哈哈哈'
print(f())
#記錄使用者的登入情況
#計算這個函數的執行時間