在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。
python裝飾器接收乙個函式,返回另乙個函式。它其實是乙個閉包(巢狀定義在非全域性作用域裡面的函式能夠記住它在被定義的時候它所處的封閉命名空間),閉包的作用在下面的裝飾器使用中可以感受到,
而返回的函式就是裝飾過的函式,它可以給原函式增加一些附加功能,而不影響原函式的呼叫方式,簡直優雅至極!
增加函式功能
假設有這麼個簡單的函式:
def
now():
print('sbingo')
現在我們想在呼叫now時,先列印一些資訊,怎麼做呢?
簡單,直接在now函式中列印就好了嘛!
but,這樣不利於**的復用,如果別的函式也要求列印呢?
那麼我們改一下,定義另乙個函式,先執行附加功能,再呼叫now,實現需求。:
def
log(f):
print('call %s():' %f.__name__)
now()
呼叫:log(now)
輸出:
call
now():
sbingo
一切看似完美,可是這樣更改後,每個呼叫now的地方都需要改為呼叫log,十分麻煩。
裝飾器的簡單使用
這時候,就該裝飾器上場了!
更改log函式:
def
log(f):
def(*args, **kw):
print('call %s():' % f.__name__)
return f(*args, **kw)
這裡log函式就是乙個裝飾器,再利用語法糖@使用這個裝飾器定義now函式:
@log這樣定義好now之後,相當於執行了:defnow
(): print('sbingo')
now = log(now)
這就是語法糖@幫我們做的事。
所以此刻請對now函式另眼相看,這很重要。
而原先呼叫now函式的地方還是一樣的呼叫方式:
now
()
卻得到了希望的輸出:
call
now():
sbingo
一切開始變得美好~
裝飾器帶引數
定義帶引數的裝飾器log:
def
log(text):
defdecorator
(func):
def(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return decorator
可以看到,帶引數的裝飾器比之前多了1層,變成了3層巢狀。
使用裝飾器log定義now函式:
@log('2017')
defnow
(): print('sbingo')
這樣定義好now之後,相當於執行了:
now = log('2017')(now)
再呼叫:now()
輸出:
2017 now():
sbingo
裝飾器的呼叫順序
裝飾器可以疊加使用,讓我們來看一下疊加後的使用順序:
定義兩個裝飾器log和log_2:
def
log(f):
print('enter log:')
def(*args, **kw):
print('log call %s():' % f.__name__)
return f(*args, **kw)
deflog_2
(f):
print('enter log_2:')
def(*args, **kw):
print('log_2 call %s():' % f.__name__)
return f(*args, **kw)
使用裝飾器log和log_2定義now函式:
@log這樣定義好now之後,相當於執行了:@log_2
defnow
(): print('sbingo')
now = log(log_2(now))
於是,在定義時就會輸出:
enter log_2:
enter log:
再呼叫:now()
輸出:
enter log_2:
enter log:
loglog_2 call
now():
sbingo
還是很好理解的。
python內建裝飾器
python中有3個內建裝飾器,都是跟class相關的:staticmethod、classmethod和property。
staticmethod 是類靜態方法,其跟成員方法的區別是沒有 self 引數,並且可以在類不進行例項化的情況下呼叫
classmethod 與成員方法的區別在於所接收的第乙個引數不是 self (類例項的指標),而是cls(當前類的具體型別)
property 是屬性的意思,利用它可以將類中的方法當做屬性使用。
總結
理解裝飾器的核心要義:
使用語法糖@定義目標函式後,目標函式已經是裝飾後的函式!
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 要理解上述 的含義,我們從自定義函式裝...