0、 概念
什麼叫裝飾器,其實也可以叫做包裝器。即對于一個既有的函數func(args),在調用它之前和之後,我們希望都做一些事情,把這個函數包裝起來。
python中的裝飾器分為兩類:函數裝飾器和類裝飾器。
這裡我們先讨論函數裝飾器。
1.不帶參數的decorator
(1) 基本用法:
- def decorator1(func):
- def dec(*args):
- print 'pre action'
- result = func(*args)
- print 'post action'
- return result
- return dec
- @decorator1
- def test_f1(name):
- print name
- return None
- test_f1('name1') #out: preaction/name1/post action
- test_f1('name2') #out: preaction/name2/post action
(2)這種現象的内部原理:
在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是被裝飾函數的參數—這種現象了。
2.帶參數的decorator
(1) 基本用法:
- def wap(name):
- def decorator1(func):
- def dec(*args):
- print name
- print 'pre action'
- result = func(*args)
- print 'post action'
- return result
- return dec
- return decorator1
- @wap('f1')
- def test_f1(name):
- print name
- return None
- @wap('f2')
- def test_f2(name):
- print name
- return None
- test_f1('name1') #out: f1/pre action/name1/post action
- test_f1('name2') #out: f2/pre action/name2/post action
帶參數的decorator,作用是通過傳遞參數可以定制不同的裝飾器。
(2) 内部原理
這裡和上面 不帶參數的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内部,使得我們可以操作這個參數。
3.函數decorator也可以修飾類成員函數
- class FOO:
- @decorator1
- def fun(self):
- print self.name
注意此時fun的self會被傳遞到decorator1中。此時把self看做普通的函數入參。
4.函數decorator的疊加
(1) 用法
- def decorator1(func):
- def dec(*args):
- print 'd1 pre'
- result = func(*args)
- print 'd1 post'
- return result
- return dec
- def decorator2(func):
- def dec(*args):
- print 'd2 pre'
- result = func(*args)
- print 'd2 post'
- return result
- return dec
- @decorator1
- @decorator2
- def test(name):
- print name
- test('test') #out: d1 pre/d2 pre/test/d1 post/d2 post
(2) 原理
- @decorator1
- @decorator2
- def test(name):
- print name
和上面的類似,内部原理是: