我們在開發乙個專案的時候,需要盡量遵循這樣乙個規則:修改是封閉的,擴充套件是開放的;也就是說在後期更改需求的時候,我們可以不改動以前的**,而只需要通過擴充套件就可以滿足新需求。python的裝飾器就是幫助我們來實現這乙個目標的方法之一。
通過乙個示例來理解裝飾器的作用,首先定義乙個列印當前時間的函式
import time
defprintcurrenttime
(): currenttime = time.time()
print("當前時間戳:" + str(currenttime))
printcurrenttime() #列印:當前時間戳:1525522986.449398
考慮這樣乙個問題:假設我們要增強printcurrenttime()函式的功能,比如,在函式呼叫前後自動列印日誌,但又不希望修改printcurrenttime()函式的定義,這種在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。
我們使用裝飾器來解決上述的問題,裝飾器其實就是乙個返回函式的高階函式。下面我們定義乙個能列印日誌的decorator,裝飾器函式pringlog接收乙個函式作為引數,並返回乙個函式,**如下:
def
pringlog
(func):
def(*args, **kw):
print('---開始呼叫函式: %s():' % func.__name__)
result = func(*args, **kw)
print('---結束呼叫函式: %s():' % func.__name__)
return result
#注意:args與kw是python中的可變引數,同時使用時,*args在前**kwargs在後
# *args表示任何多個無名引數,它是乙個tuple;
# **kwargs表示關鍵字引數,它是乙個dict。
然後我們需要借助python的@語法,把decorator置於需要增加列印log功能的函式的定義處,並在此測試這個函式:
@pringlog
defprintcurrenttime2
(): currenttime = time.time()
print("當前時間戳:" + str(currenttime))
#測試printcurrenttime2的列印效果
printcurrenttime2()
'''---開始呼叫函式: printcurrenttime2():
當前時間戳:1525523570.290186
---結束呼叫函式: printcurrenttime2():
'''
分析:pringlog()是乙個decorator,返回乙個函式,原來的printcurrenttime2()函式仍然存在,只是現在同名的printcurrenttime2變數指向了新的函式。
裝飾器中也可以傳入引數,具體的**如下:
#定義乙個高階函式,返回裝飾器的函式
defprintlogwithtext
(text):
defpringlog
(func):
def(*args, **kw):
print(text + '---開始呼叫函式: %s():' % func.__name__)
result = func(*args, **kw)
print(text + '---結束呼叫函式: %s():' % func.__name__)
return result
return pringlog
#使用裝飾器
@printlogwithtext("裝飾器引數")
defprintcurrenttime3
(): currenttime = time.time()
print("當前時間戳:" + str(currenttime))
#測試printcurrenttime3的列印效果
printcurrenttime3()
'''列印
裝飾器引數---開始呼叫函式: printcurrenttime3():
當前時間戳:1525671291.8881621
裝飾器引數---結束呼叫函式: printcurrenttime3():
'''
經過裝飾器後,如果我們在外部列印被裝飾的函式名,就會發現它們的名字變化了
解決方法:使用python內建的functools.wraps設定裝飾函式
import functools
defprintinfo
(func):
@functools.wraps(func)
def(*args, **kw):
print('---開始呼叫函式: %s():' % func.__name__)
result = func(*args, **kw)
print('---結束呼叫函式: %s():' % func.__name__)
return result
@printinfo
deftest
():pass
print(test.__name__) #列印test
Python筆記(19)函式與函式式程式設計
user bin env python coding utf 8 author berlin 1 3種程式設計方法 1 物件導向 核心內容是 類 class 2 面向過程 核心內容是 過程 def 3 函式式程式設計 核心內容是 函式 def 2 函式的定義 1 初中教學時的函式定義是 一般的,在乙...
Python學習 函式式程式設計
高階函式除了可以接受函式作為引數外,還可以把函式作為結果值返回。我們來實現乙個可變引數的求和。通常情況下,求和的函式是這樣定義的 def calc sum args ax 0 for n in args ax ax n return ax 但是,如果不需要立刻求和,而是在後面的 中,根據需要再計算怎...
python學習 函式式程式設計
函式式程式設計就是一種抽象程度很高的程式設計正規化,純粹的函式式程式語言編寫的函式沒有變數,因此,任意乙個函式,只要輸入是確定的,輸出就是確定的,這種純函式我們稱之為沒有 而允許使用變數的程式語言,由於函式內部的變數狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函式是有 的。函式式程式設計的...