您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“python裝飾器的定義及用法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“python裝飾器的定義及用法”吧!
定義:
本質(zhì)是函數(shù)(裝飾其他函數(shù)),就是為其他函數(shù)添加附加功能。
原則:
不能修改被裝飾的函數(shù)的源代碼
不能修改被裝飾函數(shù)的調(diào)用方式
先看一個(gè)完整的裝飾器的例子:
# Author: Mr.Xue
# 2019.10.23
"""
實(shí)現(xiàn)裝飾的知識(shí)儲(chǔ)備:
1、函數(shù)即‘變量’
2、高階函數(shù)
3、嵌套函數(shù)
高階函數(shù)+嵌套函數(shù)--->裝飾器
"""
import time
def timmer(func):
def warpper(*args, **kwargs):
start_time = time.time()
func()
stop_time = time.time()
print('the func run time is %s' % (stop_time - start_time))
return warpper
@timmer
def test1():
time.sleep(3)
print("in the func test1")
test1()
1、函數(shù)即“變量”
函數(shù)在內(nèi)存中的存儲(chǔ)機(jī)制:在內(nèi)存中存儲(chǔ)函數(shù)體,函數(shù)名作為門牌號(hào)
注:
python中的回收機(jī)制:不管是函數(shù)還是變量,一但"門牌號(hào)"不存在了,內(nèi)存空間就會(huì)被回收
2、高階函數(shù)
符合下面兩個(gè)條件任何一個(gè)的就是高階函數(shù):
把一個(gè)函數(shù)名作為實(shí)參傳給另一個(gè)函數(shù)
返回值中包含函數(shù)名
'''
第一種高階函數(shù):
把一個(gè)函數(shù)名作為實(shí)參傳給另一個(gè)函數(shù)
--> 實(shí)現(xiàn)了不修改被裝飾的函數(shù)bar代碼的情況下為其添加新功能
'''
import time
def bar():
time.sleep(3)
print('in the bar')
def test(func):
start_time = time.time()
print(func)
func() # run function bar
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
test(bar)
#x = bar # 函數(shù)即'變量'
#x()
'''
第二種高階函數(shù):
返回值中包含函數(shù)名
--> 不修改函數(shù)的調(diào)用方式
'''
import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func) # func的內(nèi)存地址
return func #返回func的內(nèi)存地址
print(test2(bar))
bar = test2(bar)
bar()
3、嵌套函數(shù)
在一個(gè)函數(shù)的函數(shù)體中還有一個(gè)用def聲明函數(shù)
def foo():
print("in the foo")
def bar():
print("in the bar")
bar()
foo()
好啦,理解了上面的三個(gè)知識(shí)點(diǎn)之后,我們來一步步寫一個(gè)裝飾器,首先我們先定義兩個(gè)函數(shù)test1、test2,再給兩個(gè)函數(shù)添加新的功能,計(jì)算這兩個(gè)函數(shù)的運(yùn)行時(shí)間,怎么做呢,先定義一個(gè)高階函數(shù)(上面提到的第一種高階函數(shù)),將這兩個(gè)函數(shù)當(dāng)作參數(shù)傳進(jìn)去。
import time
def deco(func):
start_time = time.time()
func() # run function bar
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
def test1():
time.sleep(3)
print('in the test1')
def test2():
time.sleep(3)
print('in the test2')
deco(test1)
deco(test2)
現(xiàn)在我們完成了裝飾器的原則之一,再不修改源代碼的基礎(chǔ)上給函數(shù)添加了新的功能。
看上去好像不難呀,接下來,只要我們改進(jìn)代碼,完成不修改函數(shù)的調(diào)用方式的這個(gè)原則,是不是就完成了呢,好,那我們將上面的高階函數(shù)改寫成第二種的高階函數(shù)
import time
def deco(func):
start_time = time.time()
return func # 返回func函數(shù)的內(nèi)存地址
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
def test1():
time.sleep(3)
print('in the test1')
def test2():
time.sleep(3)
print('in the test2')
test1 = deco(test1)
test2 = deco(test2)
test1() #沒有修改調(diào)用方式,新功能卻不見了
test2() #沒有修改調(diào)用方式
利用了第二種高階函數(shù)之后,我們完成了裝飾器的另外一個(gè)原則,沒有改變函數(shù)的調(diào)用方式,但是發(fā)現(xiàn)新功能卻沒有加上去,這時(shí)候只用高階函數(shù)來實(shí)現(xiàn)裝飾器好像有點(diǎn)困難啊,怎么辦呢?好像進(jìn)入死循環(huán)了呀。
不知道大家注意到?jīng)]有,在上面那個(gè)裝飾器的例子里面,有一行寫著,“高階函數(shù)+嵌套函數(shù)—>裝飾器”,哦,那是不是我們?cè)俑銈€(gè)嵌套函數(shù)就可以了呢,按照這個(gè)思路,我們繼續(xù)往下走。
import time
def timer(func):
def deco():
start_time = time.time()
func() # 調(diào)用func函數(shù)
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
return deco
def test1():
time.sleep(3)
print('in the test1')
def test2():
time.sleep(3)
print('in the test2')
test1 = timer(test1)
test2 = timer(test2)
test1() #沒有修改調(diào)用方式,新功能也加上去了
test2() #沒有修改調(diào)用方式,新功能也加上去了
哇哦,現(xiàn)在就已經(jīng)完成了裝飾器了,只不過調(diào)用方式看上去比較lower而已,只要修改成標(biāo)準(zhǔn)寫法就ok了。
怎么做呢,在要被裝飾的函數(shù)頭部,加上"@裝飾器名字",就好啦。
import time
def timer(func):
def deco():
start_time = time.time()
func() # 調(diào)用func函數(shù)
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
return deco
@timer # test1 = timer(test1)
def test1():
time.sleep(3)
print('in the test1')
@timer
def test2():
time.sleep(3)
print('in the test2')
test1()
test2()
只是現(xiàn)在我們寫的這個(gè)裝飾器和上面那個(gè)還有一點(diǎn)區(qū)別,我們的裝飾器沒有參數(shù),而上面的那個(gè)卻有,接下來,我們繼續(xù)完善完善。鄭州人流多少錢 http://mobile.zyyyzz.com/
給我們的內(nèi)嵌函數(shù)加上兩個(gè)非固定參數(shù),這樣就可以接收參數(shù)了,如下:
import time
def timer(func):
def deco(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs) # 調(diào)用func函數(shù)
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
return deco
@timer # test1 = timer(test1)
def test1():
time.sleep(3)
print('in the test1')
@timer
def test2(name, age):
time.sleep(3)
print('in the test2', name, age)
test1()
test2("xue", 24)
ok, all finish!
現(xiàn)在我們用裝飾器寫一個(gè)網(wǎng)站頁面的需求:比如說,一共20個(gè)網(wǎng)站,其中除了首頁不需要驗(yàn)證可以直接顯示外,其他的都需要驗(yàn)證用戶名密碼才可以顯示。
# Author: Mr.Xue
# 2019.10.24
import time
user, passwd = 'xue', 'abc123'
def auth(auth_type):
print("auth_type: ", auth_type)
def outer_warpper(func):
def warpper(*args, **kwargs):
print("warpper func args:", *args, **kwargs)
if auth_type == 'local':
username = input("Username: ")
password = input("Password: ")
if user == username and passwd == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args, **kwargs)
return res
else:
print("\033[31;1mInvalid username or password\033[0m")
elif auth_type == 'ldap':
print('bu hui gao mao xian')
return warpper
return outer_warpper
def index():
print("in the index")
@auth(auth_type='local') #home = warpper(home) -> warpper
def home():
print("in the home")
return 'from home'
@auth(auth_type='ldap')
def bbs():
print('in the bbs')
index()
print(home())
bbs()
到此,相信大家對(duì)“python裝飾器的定義及用法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。