溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python裝飾器的定義和使用方法是什么

發(fā)布時(shí)間:2022-04-12 10:40:45 來源:億速云 閱讀:200 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“Python裝飾器的定義和使用方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Python裝飾器的定義和使用方法是什么”吧!

1.裝飾器的定義

裝飾器:給已有函數(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()

2.裝飾器的通用類型的定義

(當(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'))

3.多個(gè)裝飾器同時(shí)裝飾一個(gè)函數(shù)

# 第一個(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>

4.多個(gè)裝飾器同時(shí)裝飾一個(gè)函數(shù)(二)

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()

5.類裝飾器使用方法

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()

6.使用裝飾器實(shí)現(xiàn)自動(dòng)維護(hù)路由表

路由功能:通過請求的路徑,可以找到資源的地址

# 定義一個(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í)!

向AI問一下細(xì)節(jié)

免責(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)容。

AI