python中decorator的用法及原理(一)

2021-09-07 10:41:27 字數 2187 閱讀 9744

什麼叫裝飾器,其實也可以叫做包裝器。即對於乙個既有的函式func(args),在呼叫它之前和之後,我們希望都做一些事情,把這個函式包裝起來。

python中的裝飾器分為兩類:函式裝飾器和類裝飾器。

這裡我們先討論函式裝飾器。

def

decorator1(func):

def dec(*args):

print

'pre action

'result = func(*args)

print

'post action

'return

result

return

dec

@decorator1

deftest_f1(name):

print

name

return

none

test_f1(

'name1

') #

out: preaction/name1/post action

test_f1('

name2

') #

out: preaction/name2/post action

在python內部,當你做了這件事情:

@decorator1  

def test_f1(name):

其實就是test_f1 = decorator1(test_f1)#即test_f1作為引數傳遞給func。

此後的test_f1是裝飾器中的dec函式物件了,而不是原來的函式的名稱。當呼叫test_f1(『name1』)的時候,其實呼叫的是dec(『name1』)函式,而在dec函式內部,又呼叫了func,這樣就造成了裝飾器的效果。

這也解釋了func是被裝飾函式,*arg是被裝飾函式的引數—這種現象了。

def

wap(name):

defdecorator1(func):

def dec(*args):

print

name

print

'pre action

'result = func(*args)

print

'post action

'return

result

return

dec

return

decorator1

@wap('f1

')

deftest_f1(name):

print

name

return

none

@wap('f2

')

deftest_f2(name):

print

name

return

none

test_f1(

'name1

') #

out: f1/pre action/name1/post action

test_f2('

name2

') #

out: f2/pre action/name2/post action

帶引數的decorator,作用是通過傳遞引數可以定製不同的裝飾器。

這裡和上面 不帶引數的decorator類似,

@wap('f1'

)

def test_f1(name):

內部邏輯為: test_f1 = wap(『f1』)(test_f1)

這裡wap(『f1』)返回是decorator1函式物件,這樣的 話,wap(『f1』)(test_f1)其實就是decorator1(test_f1),這樣就和上面的一樣了。只不過這裡傳遞了乙個引數』f1』進 入decorator內部,使得我們可以操作這個引數。

class

foo:

@decorator1

deffun(self):

print self.name

注意此時fun的self會被傳遞到decorator1中。此時把self看做普通的函式入參。 而且如果要使用class的屬性的話,定義fun時必須帶有self引數。

python中編寫無引數decorator

python的 decorator 本質上就是乙個高階函式,它接收乙個函式作為引數,然後,返回乙個新函式。使用 decorator 用python提供的 語法,這樣可以避免手動編寫 f decorate f 這樣的 考察乙個 log的定義 def log f deffn x print call f...

23種設計模式之裝飾模式(Decorator)

裝飾模式是一種物件結構型模式,可動態地給乙個物件增加一些額外的職責,就增加物件功能來說,裝飾模式比生成子類實現更為靈活。通過裝飾模式,可以在不影響其他物件的情況下,以動態 透明的方式給單個物件新增職責 當需要動態地給乙個物件增加功能,這些功能可以再動態地被撤銷時可使用裝飾模式 當不能採用生成子類的方...

設計模式學習之裝飾者模式(Decorator)

作用 假設我們有乙個使用了八個物件的程式,由於需求變更,其中三個物件需要另外乙個屬性。讀者可以為這三個物件建立乙個派生類,在多數情況下,這是乙個完全可以接受的方案。然而,如果這三個物件中的每個物件都要求有不同的屬性,這就意味著要建立三個派生類。更進一步,如果其中乙個類具有其他兩個類中的屬性,可能就要...