您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Python裝飾器的定義和使用方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Python裝飾器的定義和使用方法是什么”吧!
裝飾器:給已有函數(shù)增加額外的功能的函數(shù),本質(zhì)上是一個(gè)閉包函數(shù)
特點(diǎn):
1.不修改已有函數(shù)的源代碼
2.不修改已有函數(shù)的調(diào)用方式
3.給已有函數(shù)增加額外的功能
4.代碼執(zhí)行時(shí)先解析裝飾器
import time # 裝飾器原理 # def show(): # n=0 # for i in range(10000000): # n+=i # print('show_',n) # # # 定義一個(gè)閉包 # def count_time(fun): # def inner(): # start=time.time() # fun() # end=time.time() # print(f'用時(shí){end-start}秒') # return inner # # # 裝飾器在裝飾函數(shù)時(shí)的原理 # show=count_time(show) # show() # 定義裝飾器(語法糖) def count_time(fun): # 必須要有一個(gè)參數(shù)接收被裝飾函數(shù) def inner(): start=time.time() fun() end=time.time() print(f'用時(shí){end-start}秒') return inner # 裝飾器寫法:@閉包的外部函數(shù),必須在閉包定以后使用 print('解析裝飾器1') @count_time # 解釋成show=count_time(show),show指向count_time函數(shù)中的inner def show(): n=0 for i in range(10000000): n+=i print('show_',n) print('解析裝飾器2') @count_time # 解釋成display=count_time(display) def display(): print('Display') print('正式執(zhí)行...') show() display()
(當(dāng)被裝飾函數(shù)有參數(shù)或者有返回值時(shí)同樣適用)
''' 裝飾器的通用類型的定義(當(dāng)被裝飾函數(shù)有參數(shù)或者有返回值時(shí)同樣適用) ''' def outer(func): def inner(*args,**kwargs): # *為元組和列表解包,**為字典解包 print('*'*30) print(args,kwargs) ret=func(*args,**kwargs) # 解包,否則形參是元組或字典 print('*'*30) return ret return inner @outer def show(name,msg): return str(name)+' say: '+str(msg) print(show('Tom',msg='Hello'))
# 第一個(gè)閉包 def wrapper_div(func): def inner(*args,**kwargs): return '<div>'+func(*args,**kwargs)+'</div>' return inner # 第二個(gè)閉包 def wrapper_p(func): def inner(*args,**kwargs): return '<p>'+func(*args,**kwargs)+'</p>' return inner # 從下往上裝飾,從上往下執(zhí)行 @wrapper_div @wrapper_p # 定義一個(gè)函數(shù) def show(): return 'Short life I use Python.' print(show()) #<div><p>Short life I use Python.</p></div>
def outer1(func): def inner(): print('裝飾器1-1') func() print('裝飾器1-2') return inner def outer2(func): def inner(): print('裝飾器2-1') func() print('裝飾器2-2') return inner ''' 1.show指向outer1.inner 2.outer1.inner.func指向outer2.inner 3.outer2.inner.func指向show ''' @outer1 @outer2 def show(): print('Show...') show()
import time class Wrapper(): def __init__(self,func): self.func=func # 當(dāng)類中實(shí)現(xiàn)了此方法時(shí),該類的實(shí)例對象就變成了可調(diào)用對象,即可以在實(shí)例對象后面加() def __call__(self, *args, **kwargs): print('裝飾內(nèi)容1...') start=time.time() ret=self.func(*args,**kwargs) end=time.time() print(f'執(zhí)行了{(lán)end-start}秒') print('裝飾內(nèi)容2...') return ret
該裝飾器執(zhí)行完成后,被裝飾函數(shù)指向該類的實(shí)例對象
如果讓被裝飾函數(shù)執(zhí)行,那么在類中要添加__call__方法,相當(dāng)于閉包格式中的內(nèi)函數(shù)
一旦被裝飾函數(shù)執(zhí)行調(diào)用,那么就會去執(zhí)行實(shí)例對象中的__call__函數(shù)
@Wrapper #解釋成show=Wrapper(show),show變成了類的一個(gè)對象 def show(): print('Show...') show() 6.裝飾器帶有參數(shù)(使用帶有參數(shù)的裝飾器,其實(shí)是在裝飾器外面又包裹了一個(gè)函數(shù)) # @Author : Kant # @Time : 2022/1/23 22:43 def set_args(msg): def outer(func): def inner(): print('裝飾內(nèi)容',msg) func() return inner return outer ''' 使用帶有參數(shù)的裝飾器,其實(shí)是在裝飾器外面又包裹了一個(gè)函數(shù),使用該函數(shù)接收參數(shù),返回的是裝飾器 調(diào)用set_args()后會返回outer的地址引用,變成了@outer ''' @set_args('Hello') # 無論閉包函數(shù)寫成什么樣子,被裝飾函數(shù)永遠(yuǎn)指向閉包函數(shù)的內(nèi)函數(shù) def show(): print('Show...') show()
路由功能:通過請求的路徑,可以找到資源的地址
# 定義一個(gè)路由表字典 router_table={} def router(url): def wrapper(func): def inner(): print('1') print('inner-',func) # 查看當(dāng)前的被裝飾函數(shù)是誰 func() # 在這里維護(hù)路由表字典 router_table[url]=inner # 如果寫func,inner函數(shù)中的內(nèi)容都不會執(zhí)行 print('路由表字典:',router_table) return inner return wrapper @router('index.html') def index(): print('首頁內(nèi)容') @router('center.html') def center(): print('個(gè)人中心') @router('mail.html') def mail(): print('郵箱頁面') @router('login.html') def login(): print('登錄頁面') def error(): print('訪問頁面不存在') def request_url(url): func=error if url in router_table: func=router_table[url] func() print('開始執(zhí)行函數(shù)') request_url('index.html') request_url('center.html') request_url('mail.html') request_url('test.html') request_url('login.html')
到此,相信大家對“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)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。