Python高階特性之裝飾器

2021-09-25 00:27:24 字數 4349 閱讀 5721

裝飾器:定義乙個裝飾函式,函式必須返回乙個閉包(閉包就是執行時所需要的外部變數+函式物件,關於閉包的具體介紹,可參考函式,並且被裝飾的函式會被python自動傳遞給裝飾函式,作為裝飾函式的乙個引數。

裝飾器的具體定義:

1、把要裝飾的方法作為輸入引數;

2、在函式體內可以進行任意的操作(可以想象其中會有很多應用場景);

3、只要確保最後返回乙個可執行的函式即可(可以是原來的輸入引數函式,也可以是乙個新函式)。

裝飾器的分類

裝飾器分為無引數decorator和有引數decorator

無引數decorator:生成乙個新的裝飾器函式

有引數decorator:裝飾函式先處理引數,再生成乙個新的裝飾器函式,然後對函式進行裝飾。

使用裝飾器,需要在其他函式的上面寫個@***xx,如下面例子的@timer

舉個例子,使用裝飾器來計算執行乙個函式的耗時:

import time

def timer(func): #裝飾函式

time1=time.time()#被裝飾函式呼叫前做的事情

print("******before******")

func(*arg,**kw) #做一次函式呼叫

time2=time.time()#被裝飾函式呼叫後做的事情

print("******after******")

print("time elapsed:%s" %(time2-time1)) #計算執行被裝飾函式的耗時

@timer

def a(count): #被裝飾函式

print("執行次數:",count)

裝飾器其實就是乙個閉包,把乙個函式當做引數後返回乙個替代版函式。

裝飾函式中的閉包函式結構如下:

*** 幹一些事情

func(*arg,**kw) #執行被裝飾函式

yyy 幹另外一些事情

裝飾器的規則:

規則1:

函式func上面定義了@***x,那麼等價於 func = ***x(func)

規則2:

裝飾函式***x,必須返回乙個閉包(乙個內建函式+func)

下面來具體分析一下裝飾器整個執行過程

def deco(func):

def _deco():

print ("before myfunc() called.")

func()

print (" after myfunc() called.")

# 不需要返回func,實際上應返回原函式的返回值

return _deco

@deco #myfunc=deco(myfunc)

def myfunc():

print (" myfunc() called.")

return 'ok'

#myfunc=deco(myfunc)—>返回了乙個閉包:_deco+myfunc

myfunc() #---->執行閉包函式_deco()

myfunc() #---->執行閉包函式_deco()

執行邏輯:

deco(myfunc)

print (「before myfunc() called.」)

myfunc()

print (" after myfunc() called.")

print (" myfunc() called.")

print (" myfunc() called.")

執行過程解釋:

裝飾函式deco

被裝飾函式myfunc

@deco

def myfunc(): —>myfunc= deco(myfunc)

myfunc = deco(myfunc)幹了什麼呢?

1 呼叫了deco(myfunc)

2 返回閉包:_deco+外包變數myfunc

3 閉包賦值給了myfunc

4 提醒myfunc變為了閉包函式物件

myfunc()—>幹了什麼呢?

1 _deco()執行了

2 print (「before myfunc() called.」)

3 myfunc()

4 print (" after myfunc() called.")

myfunc()—>幹了什麼呢?

1 _deco()執行了

2 print (「before myfunc() called.」)

3 myfunc()

4 print (" after myfunc() called.")

執行結果:

被裝飾函式帶引數

def deco(func):

def _deco(*arg,**kw):

print ("before %s called." %func.__name__)

print(func(*arg,**kw))

print (" after %s called." %func.__name__)

# 不需要返回func,實際上應返回原函式的返回值

return _deco

#閉包:_deco+func

裝飾器帶引數

def deco(s):

def __deco(func):

def _deco(*arg,**kw):

print ("before %s called." %func.__name__,s)

print(func(*arg,**kw))

print (" after %s called." %func.__name__,s)

# 不需要返回func,實際上應返回原函式的返回值

return _deco

return __deco

#閉包:_deco+func

@deco("hello")

def myfunc(a,b):

print (" myfunc() called.")

return a+b

myfunc(1,2)

myfunc(3,4)

1)多了一步:deco(「hello」) —>返回了閉包:__deco+s

deco=閉包:__deco+s

2)@deco—>__deco(func)+s—>返回了乙個閉包_deco+func+s

後面的過程跟上一步的過程一樣。

內建裝飾器

python中內建的裝飾器有三個:

staticmethod:定義例項方法為靜態方法

classmethod:定義例項方法為類方法

property:對類屬性的操作

乙個函式可以同時被多個裝飾器進行裝飾,

同時對乙個函式使用多個不同的裝飾器進行裝飾時,裝飾器的順序是怎樣的呢?

@a

@b@c

def f():

pass

等價於:

f = a(b(c(f)))

python高階特性(裝飾器)

裝飾器本質上是乙個函式,該函式用來處理其他函式,它可以讓其他函式在不需要修改 的 前提下增加額外的功能,裝飾器的返回值也是乙個函式物件。它經常用於有切面需求的場景,比如 插入日誌 效能測試 事務處理 快取 許可權校驗等應用場景。首先我們先了解以下通用裝飾器的框架,幫助我們更好地理解裝飾器的用法 de...

Python高階之裝飾器

要理解python裝飾器,首先要明白在python中,函式也是一種物件,因此可以把定義函式時的函式名看作是函式物件的乙個引用。既然是引用,因此可以將函式賦值給乙個變數,也可以把函式作為乙個引數傳遞或返回。同時,函式體中也可以再定義函式。可以通過編寫乙個純函式的例子來還原裝飾器所要做的事。def de...

python語言特性之裝飾器

首先,python裝飾器的作用是 在不改變原有函式實現的前提下,給此函式增加一些額外的功能 在原有函式呼叫之前或者呼叫之後 好像給原有函式加上了乙個裝飾的殼子。通過乙個例子解釋python裝飾器 coding utf8 def w1 func def inner args,kwargs print ...