python裝飾器的詳細解析

2022-06-07 08:36:13 字數 4242 閱讀 1636

寫在前面:

python裝飾器(fuctional decorators)就是用於拓展原來函式功能的一種函式,目的是在不改變原函式名(或類名)的情況下,給函式增加新的功能。 這個函式的特殊之處在於它的返回值也是乙個函式,這個函式是內嵌「原「」函式的函式。

一般而言,我們要想拓展原來函式**,最直接的辦法就是侵入**裡面修改,例如:

import

time

deff():

print("

hello")

time.sleep(1)

print("

world

")

這是我們最原始的的乙個函式,然後我們試圖記錄下這個函式執行的總時間,那最簡單的做法就是改動原來的**:

import

time

deff():

start_time =time.time()

print("

hello")

time.sleep(1)

print("

world")

end_time =time.time()

execution_time = (end_time - start_time)*1000

print("

time is %d ms

" %execution_time)

但是實際工作中,有些時候核心**並不可以直接去改,所以在不改動原**的情況下,我們可以再定義乙個函式。(但是生效需要再次執行函式)

import

time

defdeco(func):

start_time =time.time()

func()

end_time =time.time()

execution_time = (end_time - start_time)*1000

print("

time is %d ms

" %execution_time)

deff():

print("

hello")

time.sleep(1)

print("

world")

if__name__ == '

__main__':

deco(f)

print("

f.__name__ is

",f.__name__

)

print()

這裡我們定義了乙個函式deco,它的引數是乙個函式,然後給這個函式嵌入了計時功能。

但是想要拓展這一千萬個函式功能,就是要執行一千萬次deco()函式,所以這樣並不理想!

接下來,我們可以試著用裝飾器來實現,先看看裝飾器最原始的面貌。

import

time

defdeco(f):

def start_time =time.time()

f()end_time =time.time()

execution_time = (end_time - start_time)*1000

print("

time is %d ms

" %execution_time )

return

@deco

deff():

print("

hello")

time.sleep(1)

print("

world")

if__name__ == '

__main__':

f()

這裡的deco函式就是最原始的裝飾器,它的引數是乙個函式,然後返回值也是乙個函式。

f()函式就相當於被注入了計時功能,現在只要呼叫f(),它就已經變身為「新的功能更多」的函式了(不需要重複執行原函式)。 

擴充套件1:帶有固定引數的裝飾器

import

time

defdeco(f):

def start_time =time.time()

f(a,b)

end_time =time.time()

execution_time = (end_time - start_time)*1000

print("

time is %d ms

" %execution_time)

return

@deco

deff(a,b):

print("

be on")

time.sleep(1)

print("

result is %d

" %(a+b))

if__name__ == '

__main__':

f(3,4)

擴充套件2:無固定引數的裝飾器

import

time

defdeco(f):

start_time =time.time()

f(*args, **kwargs)

end_time =time.time()

execution_time_ = (end_time - start_time)*1000

print("

time is %d ms

" %execution_time)

return

@deco

deff(a,b):

print("

be on")

time.sleep(1)

print("

result is %d

" %(a+b))

@deco

deff2(a,b,c):

print("

be on")

time.sleep(1)

print("

result is %d

" %(a+b+c))

if__name__ == '

__main__':

f2(3,4,5)

f(3,4)

擴充套件3:使用多個裝飾器,裝飾乙個函式

import

time

defdeco01(f):

print("

this is deco01")

start_time =time.time()

f(*args, **kwargs)

end_time =time.time()

execution_time = (end_time - start_time)*1000

print("

time is %d ms

" %execution_time)

print("

deco01 end here")

return

defdeco02(f):

print("

this is deco02")

f(*args, **kwargs)

print("

deco02 end here")

return

@deco01

@deco02

deff(a,b):

print("

hello,here is a func for add :")

time.sleep(1)

print("

result is %d

" %(a+b))

if__name__ == '

__main__':

f(3,4)

'''

this is deco01

this is deco02

hello,here is a func for add :

result is 7

deco02 end here

time is 1003 ms

deco01 end here

'''

裝飾器呼叫順序

裝飾器是可以疊加使用的,那麼使用裝飾器以後**是啥順序呢?

對於python中的」@」語法糖,裝飾器的呼叫順序與使用 @ 語法糖宣告的順序相反。在這個例子中,」f(3, 4) = deco01(deco02(f(3, 4)))」。

參考:

python裝飾器解析 Python裝飾器詳解

按照 python 的程式設計原則,當乙個函式被定義後,如要修改或擴充套件其功能應盡量避免直接修改函式定義的 段,否則該函式在其他地方被呼叫時將無法正常執行。因此,當需要修改或擴充套件已被定義的函式的功能而不希望直接修改其 時,可以使用裝飾器。先來看乙個簡單的例子 def func1 functio...

Python裝飾器詳細舉例

coding utf 8 author mr.luo date 2021 2 19 15 23 def too print 豬八戒 基礎的函式呼叫操作 print 豬八戒到底是哪八戒 center 20,too a too print type a a 基本的函式引數傳遞操作 print 豬八戒到底...

python裝飾器解析(一)

裝飾器是一種著名的設計模式,允許我們動態的為乙個物件來新增一些額外的功能而無需去修改它所在的類或者是建立新類。python中的函式也是一種物件,下面用幾個函式例項來說明python中的裝飾器。首先從最簡單的開始,假設我們有如下的函式 def my func print do something 現在...