裝飾器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,正好可以列印兩個字元,如果這個時候有新的字元傳過來,那...