溫馨提示×

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

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

Python裝飾器原理與基本用法分析

發(fā)布時(shí)間:2020-08-25 11:08:03 來(lái)源:腳本之家 閱讀:162 作者:隨風(fēng)行云 欄目:開(kāi)發(fā)技術(shù)

本文實(shí)例講述了Python裝飾器原理與基本用法。分享給大家供大家參考,具體如下:

裝飾器:

意義:在不能改變?cè)瘮?shù)的源代碼,和在不改變整個(gè)項(xiàng)目中原函數(shù)的調(diào)用方式的情況下,給函數(shù)添加新的功能

由于不允許改變函數(shù)的源代碼,在忽略調(diào)用方式的情況下,我們可能會(huì)有以下結(jié)果:

def decorator(func):
  func()
  print("logging")
def test1():
  print("test1")
def test2():
  print("Test2")
decorator(test1)
decorator(test2)

但這改變了原本的調(diào)用方式,原本是test1(),現(xiàn)在是decorator(test1)

那么如果我們?yōu)榱耸拐{(diào)用方式不變,是否可以使裝飾好的函數(shù)decorator的返回值是一個(gè)我們需要的函數(shù),再賦值給原來(lái)的函數(shù)名呢?

于是:

def timmer1(func):
  def warpper():
    start_time = time.time()
    func()
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
   return warpper
test3=timmer1(test3)

好像上面這段代碼并沒(méi)有改變?cè)瓉?lái)的調(diào)用方式,調(diào)用原來(lái)的test3,相當(dāng)于運(yùn)行timmer1中的warpper

如果對(duì)于無(wú)參數(shù)的函數(shù)來(lái)說(shuō),上面的代碼已經(jīng)實(shí)現(xiàn)了我們的目的,但對(duì)于帶參數(shù)的函數(shù),上面的代碼沒(méi)有傳入?yún)?shù),所以仍然需要修改

于是:

def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper

在上上面的代碼中,由于實(shí)質(zhì)上,test3已經(jīng)等于wrapper,所以可以直接使用,test3(參數(shù))來(lái)傳入?yún)?shù),為了處理參數(shù)不確定數(shù)量問(wèn)題,可以使用可變長(zhǎng)度參數(shù)

上面代碼還存在一個(gè)問(wèn)題,無(wú)法獲取原本函數(shù)中的返回值,那么我們還需要加上一些東西:

import time
def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    return res
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper

使用一個(gè)變量記錄下原函數(shù)的返回值。

這樣我們就實(shí)現(xiàn)了裝飾器的基本功能。

補(bǔ)充:

python提供了一個(gè)功能:

@裝飾器名
def 目標(biāo)裝飾函數(shù)名():
  pass
#上面的效果是 目標(biāo)裝飾函數(shù)名=裝飾器(目標(biāo)裝飾函數(shù)名)

所以在需要替換原函數(shù)的時(shí)候,可以在目標(biāo)裝飾函數(shù)定義的上一行加上@裝飾器名

所以上面的代碼會(huì)變成:

def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper
@timmer2
def test7():
  print("test7")
@timmer2
def test6(x):
  print(x)
test7()
test6(2)

import time
def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    return res
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper
@timmer2
def test4():
  print("test4 run")
  return "test4 done"
test4()
print("--------")
print(test4())

第二個(gè)補(bǔ)充:

可以一個(gè)函數(shù),可以使用多個(gè)裝飾器

比如:

@裝飾器1

@裝飾器2

更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結(jié)》及《Python入門與進(jìn)階經(jīng)典教程》

希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。

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

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

AI