摘要:裝飾器介紹中的裝飾器的目的是為一個目標函數添加額外的功能卻不修改函數本身。裝飾器的本身其實是一個特殊的函數。那么有啥更好的解決方式呢裝飾器代碼像上面這么寫,可以較好地解決了上面提到的第一個問題。裝飾器語法糖放在函數前面,相當于執行了等。
怎么理解python中的裝飾器 一個比喻
知乎上有一個比較形象的比喻 https://www.zhihu.com/questio...:
人類穿著內褲很大程度上是為了遮羞和對關鍵部位進行保護,但是卻不能提供保暖。因此我們還需要穿著長褲。長褲就是對內褲功能的補充,卻不影響內褲本身的功能。
python中的裝飾器的目的是為一個目標函數添加額外的功能卻不修改函數本身。裝飾器的本身其實是一個特殊的函數。主要的應用場景有插入日志,性能測試、事務處理等。
下面我們來舉一個簡單的例子一步一步了解一下。我們首先寫了三個函數,即對兩個數做加減乘的操作并打印:
def func_sum(x, y): print x+y def func_minus(x, y): print x - y def func_multiply(x, y): print x*y
但是我們現在有了新需求,就是需要在日志中打印所有加、減、乘操作時的時間。
import logging import time def func_sum(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) print x+y def func_minus(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) print x - y def func_multiply(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) print x*y
顯然像上面這樣修改每一個函數,在每一個函數中添加重復代碼是不合適的。真正理想的是我們可以定義一個函數,專門用來輸出日志,輸出完日志后,再執行真正的函數。
import logging import time def func_sum(x, y): print x+y def func_minus(x, y): print x - y def func_multiply(x, y): print x*y def logging_first(func): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) return func logging_first(func_sum)(20,30)
但是上面這中實現方式也存在著種種問題。
log其實是logging_first(func_sum)時就打印了,而不是進行加、減、乘的時候打印的。
對加減乘函數的調用都需要修改成logging_first(func_sum)(20,30)類似方式。
那么有啥更好的解決方式呢?
import logging import time def func_sum(x, y): print x+y def func_minus(x, y): print x - y def func_multiply(x, y): print x*y def logging_first(func): def wrapper(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) return func(x, y) return wrapper logging_first(func_sum)(20, 30)
代碼像上面這么寫,可以較好地解決了上面提到的第一個問題。調用logging_first返回的是wrapper函數。執行wrapper函數的時候先打印log,然后馬上執行了傳入的func函數。
但是調用方式依舊需要修改成logging_first(func_sum)(20, 30)這種方式。
幸好,python給我們提供了優雅的語法糖。
我們可以將上面的代碼修改成以下形式。
import logging import time def logging_first(func): def wrapper(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) return func(x, y) return wrapper @logging_first def func_sum(x, y): print x + y @logging_first def func_minus(x, y): print x - y @logging_first def func_multiply(x, y): print x * y func_sum(20, 30) func_minus(20, 30) func_multiply(20, 30)
裝飾器語法糖放在函數前面,相當于執行了logging_firts(func_sum)等。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38250.html
摘要:前言最近跟著流暢的和學習,看到裝飾器部分,有些頭大倒不是因為概念難以理解,而是書和網上文章中有些地方有些矛盾之處在簡單學習和實踐之后,整理出我對裝飾器的理解如下裝飾器的定義在不同語境下,裝飾器有不一樣的含義,我大致認為有種定義一種把另一個對 前言 最近跟著《流暢的Python》和《Python Cookbook》學習,看到裝飾器部分,有些頭大倒不是因為概念難以理解,而是書和網上文章中有...
摘要:實現一個簡單的裝飾器輸出被裝飾函數的運行時間簡單運用運行結果運行過程中,首先輸出裝飾器函數中的內容被裝飾函數運行時間長度函數名稱和實際參數計算結果然后得到最終的計算結果。 函數裝飾器 函數裝飾器用于在源碼中標記函數, 以某種方式增強函數的行為,這是一個強大的功能。 函數裝飾器是一個可調用對象,其參數是另外一個函數,即被裝飾函數。裝飾器可能處理被裝飾函數,然后將其返回,或者將其替換成另一...
摘要:設計模式學習裝飾器模式這個在我的筆記中有介紹工廠模式未完成,待更新單例模式保證一個對象最多只有一個實例存在。對安全性要求較高的場景,比如銀行的修改余額業務。如果我們不使用單例模式,那么就會創建三個不同的實例。 設計模式學習 1.裝飾器模式 這個在我的筆記中有介紹 2.工廠模式 author : liibntime :2018-11-6未完成,待更新 3.單例模式 保證一個對象最多只有一...
摘要:的裝飾器可以實現在代碼運行期間修改函數的上下文,即可以定義函數在執行之前進行何種操作和函數執行后進行何種操作,而函數本身并沒有任何的改變。中的參數,實際上則是傳遞給實際上是的參數因為裝飾器也是個函數,那么裝飾器自己的能不能有參數傳遞呢。 Python的裝飾器可以實現在代碼運行期間修改函數的上下文, 即可以定義函數在執行之前進行何種操作和函數執行后進行何種操作, 而函數本身并沒有任何的改...
閱讀 2048·2019-08-30 15:52
閱讀 2440·2019-08-29 18:37
閱讀 790·2019-08-29 12:33
閱讀 2839·2019-08-29 11:04
閱讀 1523·2019-08-27 10:57
閱讀 2092·2019-08-26 13:38
閱讀 2759·2019-08-26 12:25
閱讀 2445·2019-08-26 12:23