一卦停、什么是裝飾器
? ? ? ?裝飾器本質(zhì)上是一個(gè)Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對象宝穗。它經(jīng)常用于有切面需求的場景鸽照,比如:插入日志螺捐、性能測試、事務(wù)處理矮燎、緩存定血、權(quán)限校驗(yàn)等場景。裝飾器是解決這類問題的絕佳設(shè)計(jì)诞外,有了裝飾器澜沟,我們就可以抽離出大量與函數(shù)功能本身無關(guān)的雷同代碼并繼續(xù)重用。
二峡谊、以下是一個(gè)時(shí)間模塊插入日志的裝飾器
import functools
import time
def add_logs(func):
'''
1.創(chuàng)建裝飾器茫虽,創(chuàng)建add_log裝飾器刊苍, 被裝飾的函數(shù)打印日志信息;
2. 日志格式為: [字符串時(shí)間] 函數(shù)名: xxx濒析, 運(yùn)行時(shí)間:xxx, 運(yùn)行返
? ? :paramfunc:
? ? :return:
'''
? ? def wrapper(*args,**kw):
start_time = time.time()
res = func(*args,**kw)
end_time = time.time()
print ('函數(shù)名:{0} 運(yùn)行時(shí)間:{1}'.format(func.__name__ , (end_time - start_time)))
return res
return wrapper
@add_logs
def add(x,y):
time.sleep(1)
return x+y
a = add(1,20)
print(a)
從上面的例子中可以可以看出:裝飾器就是一個(gè)閉包正什,閉包的定義:在一個(gè)內(nèi)部函數(shù)中,對外部作用域的變量進(jìn)行引用号杏,(并且一般外部函數(shù)的返回值為內(nèi)部函數(shù))婴氮,那么內(nèi)部函數(shù)就被認(rèn)為是閉包。
三盾致、介紹一個(gè)用戶權(quán)限模塊的裝飾器案例:
# Create an account
user_auth = [{'username':'lufei','password':'123456'}]
# # 初始登錄狀態(tài)信息
# current_dic = {'username': None, 'login': False}
# Initial login status information
login_dic = {'username':None, 'login':False}
# Create login function decorator
def auth_func(func):
def wrapper(*args,**kwargs):
if login_dic['username']and login_dic['login']:
res = func(*args, **kwargs)
return res
while True:
username =input('plase input username:')
password =input('plase input password:')
for user_dicin user_auth:
if username == user_dic['username']and password == user_dic['password']:
login_dic['username'] = username
login_dic['login'] =True
? ? ? ? ? ? ? ? ? ? res = func(*args, **kwargs)
return res
else:
print('password is error')
return wrapper()
@auth_func
def index():
print('歡迎來到天貓購物商城')
@auth_func
def shoppingcar():
print('購物車:%s主经,%s,%s' % ('火鍋底料', '三明治', '冰淇淋'))
index()
shoppingcar()
從上面的例子可以看出來我們用裝飾器做了一個(gè)登錄模塊的驗(yàn)證功能的裝飾器庭惜,驗(yàn)證用戶是否登錄成功罩驻,一個(gè)電商網(wǎng)站很多模塊都要判斷用戶的的權(quán)限,只有用戶登錄成功护赊,采用權(quán)限下單惠遏,支付,評價(jià)等等操作百揭,我們不需要每一個(gè)模塊都要驗(yàn)證用戶的登錄狀態(tài)爽哎,只需要寫一個(gè)判斷登錄權(quán)限的裝飾器就完美解決了,大大的提高了代碼的冗余和開發(fā)的效率器一。
四课锌、介紹一個(gè)用戶緩存模塊的裝飾器案例
緩存的應(yīng)用場景:數(shù)據(jù)在需要頻繁查詢,且每次查詢都需要大量計(jì)算或者等待時(shí)間之后才能返回結(jié)果的情況祈秕,使用緩存來提高查詢速度渺贤,用內(nèi)存空間換取查詢、加載的時(shí)間请毛。
那緩存應(yīng)該采用什么數(shù)據(jù)結(jié)果呢志鞍?
1.便于查詢的,且能快速獲得數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)方仿,每次查詢的時(shí)候固棚,只要輸入一致,就應(yīng)該得到同樣的結(jié)果(順序也一致仙蚜,例如減法函數(shù)此洲,參數(shù)順序不一致,結(jié)果不一樣)基于上面的分析委粉,此數(shù)據(jù)結(jié)構(gòu)應(yīng)該是字典呜师。
import time
import datetime
def cache(d={},cache_time=3):
def _cache(func):
def wrapper(*args,**kwargs):
if d.get(args)is None or datetime.datetime.now().timestamp()-d[args][1]>cache_time:
value = func(*args,**kwargs)
d[args] = (value,datetime.datetime.now().timestamp())
return value
else:
print('using cache')
print(d[args][0])
return d[args][0]
return wrapper
return _cache
@cache(cache_time=15)
def test_func(x,y):
print(x**y)
return x**y
test_func(1,2)
time.sleep(4)
test_func(1,2)
test_func(2,4)
test_func(2,4)
參考文獻(xiàn):https://blog.csdn.net/weixin_43936969/article/details/103823711
參考文獻(xiàn):https: // blog.csdn.net / maergaiyun / article / details /82724679