Python 裝飾器一說

2021-07-24 11:12:31 字數 3239 閱讀 1394

裝飾器decorator,是在**執行期間動態增加功能的方式,其實體現了一種設計模式即強調的是開放封閉原則,現對其定義不做多的說明,主要為其敲黑板記重點。

decorator就是乙個返回函式的高階函式。現模擬乙個打招呼場景。

def

sayhello

(func):

defhow

(*args, **kw):

print('how about u %s' % func.__name__)

return func(*args, **kw)

return how

@sayhello

defjack

(): print('i am fine')

jack()

輸出結果為:

how about u jack

i am fine

我們在一開始定義了sayhello這個裝飾器,引數接收函式並返回函式。根據語法知識,將@sayhello置於函式jack()上方,且只能放在被裝飾的函式的上方最近處,不能空行

當程式執行到函式jack()時,則會開始執行@sayhello內的函式。

實際上是相當於執行了jack= sayhello(jack),此時變數名jack則指向了內部函式指向的函式體記憶體位址,而不再指向它原來的函式體的記憶體位址。

內部函式how的引數定義是(*args, **kw),可以接受任意引數的呼叫。於是先列印出了how about u+jack函式名,接著再呼叫回函式jack()。

此時再次列印函式名jack._name_時,會列印的不是原來的jack()而是how(),具體原因可看上述,為了避免依賴於**簽名的程式報錯,應在內部函式how()上面新增

@functools.wraps(func)

接下來拓展下如何編寫能在函式呼叫的前後都有列印語句的寫法

def

sayhello

(func):

defhow

(*args, **kw):

print('how about u? %s' % func.__name__)

result = func(*args, **kw)

print('i am fine too!')

return result

return how

@sayhello

defjack

(): print('i am fine, and u?')

jack()

列印結果為

how about u? jack

i am fine, and u?

i am fine too!

要注意的是,result = func(*args, **kw)不能寫為result = func,因為這表示將func函式的函式名當做引數傳遞給result,實際上是乙個none值。

若原始引數需要引數呢,那我們就可以使用萬能引數*args和**kw,比如從原始函式傳遞乙個goodmorning問候

def

sayhello

(func):

defhow

(*args, **kw):

print('how about u? %s' % func.__name__)

result = func(*args,**kw)

print('i am fine too!')

return result

return how

@sayhello

defjack

(today):

print("%s, i am fine, and u?"%today)

jack("goodmorning ")

輸出結果為

how about u? jack

goodmorning , i am fine, and u?

i am fine too!

若decorator本身需要傳入引數,那就需要編寫乙個返回decorator的高階函式,如傳入乙個時間

def

funlog

(time):

defsayhello

(func):

defhow

(*args, **kw):

print('%s' %time)

return func(*args,**kw)

return how

return sayhello

@funlog('2016-11-8')

defjack

(): print("i am fine")

jack()

輸出結果為

2016-11-8

i am fine

乙個原始函式也可以被多個函式修飾,但要注意@語法順序

def

sayhello

(func):

defone

(*args, **kw):

print('onebegin' )

result1 = func(*args,**kw)

print('oneover' )

return result1

return one

defsayhi

(func):

deftwo

(*args, **kw):

print('twobegin' )

result2 = func(*args,**kw)

print('twoover' )

return result2

return two

@sayhello

@sayhi

defjack

(): print("jack")

jack()

輸出結果如下

onebegin

twobegin

jack

twoover

oneover

說一說瀏覽器快取

快取的問題一直都是我們比較頭痛的問題,為了提高 響應速度,減少伺服器的負擔,和節省頻寬,將需要將靜態資源快取在客戶端,http 快取相關的幾個重要的header cache control cache control 這是http快取最重要的頭部字段,用於指定所有快取機制在整個請求 響應 中必須服從...

說一說瀏覽器快取

快取的問題一直都是我們比較頭痛的問題,為了提高 響應速度,減少伺服器的負擔,和節省頻寬,將需要將靜態資源快取在客戶端,http 快取相關的幾個重要的header cache control cache control 這是http快取最重要的頭部字段,用於指定所有快取機制在整個請求 響應 中必須服從...

說一說 r與 n

今天在用python讀取txt檔案的時候,遇到了乙個比較坑的問題,那就是 n 和 r 究竟有什麼區別?在計算機還沒有出現之前,人們設計了一種機器叫做電傳打字機,這種機器每秒鐘可以打10個字元。不過它有個問題,就是打完一行換行的時候,需要0.2s,正好可以列印兩個字元,如果這個時候有新的字元傳過來,那...