Python學習 19 函式式程式設計 裝飾器

2021-08-20 15:13:06 字數 2647 閱讀 4879

我們在開發乙個專案的時候,需要盡量遵循這樣乙個規則:修改是封閉的,擴充套件是開放的;也就是說在後期更改需求的時候,我們可以不改動以前的**,而只需要通過擴充套件就可以滿足新需求。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學習 函式式程式設計

函式式程式設計就是一種抽象程度很高的程式設計正規化,純粹的函式式程式語言編寫的函式沒有變數,因此,任意乙個函式,只要輸入是確定的,輸出就是確定的,這種純函式我們稱之為沒有 而允許使用變數的程式語言,由於函式內部的變數狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函式是有 的。函式式程式設計的...