Python的裝飾器 decorator

2021-06-27 11:22:57 字數 2938 閱讀 2186

python的裝飾器是乙個非常有趣的特性。但是如果對decorator這一設計模式或者對python語言不了解,初次看到這樣的**恐怕會覺得難以理解:

def baselog_decorator(func):

return func(msg)

下面結合例子說明一下python中裝飾器的用法。

比如我們現在有乙個函式處理使用者請求:

def request(msg):

print('request', msg)

在不改變現有函式功能前提下,我們希望能夠在處理使用者請求時列印日誌資訊(可以認為是為了除錯用)。

定義乙個裝飾函式baselog_decorator,接受乙個func作為入參。

def baselog_decorator(func):    

return func(msg)

有兩點需要注意:

1)python的函式內部可以定義函式;

2)  python的函式定義可以作為乙個物件返回。

python 的decorator的魔法盡在於此。

接下來,這樣定義函式request:

@baselog_decorator

def request(msg):

print('request', msg)

這個寫法其實等價於: 

request = baselog_decorator(request)

相當於呼叫乙個經過baselog_decorator 處理後的新的函式物件。

當你呼叫request, 比如 request('hahaha'),就會得到:

現在大家對裝飾器應該有個基本的了解了。下面我們看一下更複雜一些的應用。

目前我們看過的裝飾器還只是乙個接受被裝飾函式做為唯一入參的函式,我們希望裝飾器可以接受引數,根據不同引數其行為也有變化。

比如我們的request響應使用者請求,分為普通使用者和vip使用者。我們的裝飾器提供日誌功能,但是對於不同使用者的日誌級別不同,普通使用者輸出到螢幕,vip使用者輸出到伺服器進行記錄。那麼如何接受定製引數(比如級別)呢?我們需要一些更加「**」的魔法。

請大家看一下下面這個例子。normal_request和vip_request 是兩種不同級別的使用者的請求處理函式,我們需要為它們增加log資訊,而對應log資訊的實際處理應該有所不同。

def normal_request(msg):

print('normal_request', msg)

def vip_request(msg):

print('vip_request', msg)

我們期望的log輸出的裝飾器是這樣,不但可以接受功能函式func,還可以指定級別:

def log_decorator(func, level):

if level is 'normal':

print('normal user action put to screen.')

else:

print('vip action put to server.')

return func(msg)

@log_decorator('normal') #使用時可以指定按'normal'級別裝飾。

那麼我們該怎麼做呢?我們需要為裝飾器再定義裝飾器。

如下是我們新定義的裝飾器。

def arg_decorator(decorator_func):                        #此裝飾器接受功能裝飾器(本例是提供log功能)

def arg_maker(*args, **kwargs): #此裝飾器返回了乙個新的函式arg_maker, 其接受定製引數

return decorator_func(func, *args, **kwargs) #arg_maker 返回的包裝函式內部,呼叫功能裝飾器,並傳入定製引數

return arg_maker

#使用起來像這樣:
@arg_decorator                                            #用arg_decorator 裝飾我們的功能裝飾器,增加引數定製能力。

def log_decorator(func, level): #這個裝飾器函式不但接受func,還帶level引數,正是我們想要的。

if level is 'normal':

print('normal user action put to screen.')

else:

print('vip action put to server.')

return func(msg)

#下面就是根據實際級別要求裝飾函式了。 

@log_decorator('normal')

def normal_request(msg):

print('normal_request', msg)

@log_decorator('vip')

def vip_request(msg):

print('vip_request', msg)

大家是不是有點暈呢,敲一下**試一下吧。裝飾器在python中有廣泛應用,比如@property和@staticmethod,應該要掌握這個知識。

python裝飾器 Python 裝飾器

簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...

python裝飾器 裝飾器

由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now 現在,假設我們要增強now 函式的...

python裝飾器原理 Python裝飾器原理

裝飾器 decorator 是物件導向設計模式的一種,這種模式的核心思想是在不改變原來核心業務邏輯 的情況下,對函式或類物件進行額外的修飾。python中的裝飾器由python直譯器直接支援,其定義形式如下 decorator def core service 要理解上述 的含義,我們從自定義函式裝...