Python之裝飾器
裝飾器本質(zhì)上是一個Python函數(shù)似舵,它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能
,裝飾器的返回值也是一個函數(shù)對象缩焦。它經(jīng)常用于有切面需求的場景欲芹,比如:插入日志衙传、性能測試、事務(wù)處理蚓胸、緩存挣饥、權(quán)限校驗等場景。裝飾器是解決這類問題的絕佳設(shè)計沛膳,有了裝飾器扔枫,我們就可以抽離出大量與函數(shù)功能本身無關(guān)的雷同代碼并繼續(xù)重用。概括的講锹安,裝飾器的作用就是為已經(jīng)存在的對象添加額外的功能短荐。
它可以裝飾的東西有:函數(shù)、類
由以下例子來講述叹哭,
part1簡單裝飾器
假如說我們由一個需求忍宋,計算兩個數(shù)字的和
def sum(x, y):
print ("The sum is: " + str(x + y))
現(xiàn)在我們需要對需求加以改進,加上函數(shù)執(zhí)行的時間风罩。
那么不使用裝飾器的代碼糠排,我們可能會按以下方式實現(xiàn):
In [11]: import time
In [12]: def sum(x, y):
...: begin_time = time.time()
...: value = x + y
...: print ("The time cost is: %s " %(time.time() - begin_time))
...: return value
...:
但是這時候,我們發(fā)現(xiàn)超升,代碼不是很和諧入宦。 不符合pythonic哺徊。
那么這時候,我們可以使用裝飾器了
# 先定義一個裝飾器
def time_cost(func):
def wrapper(x, y):
begin_time = time.time()
value = func(x, y)
print("The time cost is %s" %(time.time() - begin_time))
return value
return wrapper
# 使用裝飾器
@time_cost
def sum(x, y):
return x + y
這時候我們再次調(diào)用sum()
函數(shù)時云石,跟剛開始我們實現(xiàn)的結(jié)果一樣唉工,但是對于我們的代碼而言,卻更加的簡潔汹忠,工整淋硝。
part2 帶參數(shù)的裝飾器
我們也可以對裝飾器加上參數(shù)。
我們以另一個例子來解釋:
def use_logging(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == "warn":
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper
return decorator
@use_logging(level="warn")
def foo(name='foo'):
print("i am %s" % name)
在上述的use_logging
是允許帶參數(shù)的裝飾器宽菜。它實際上是對原有裝飾器的一個函數(shù)封裝谣膳,并返回一個裝飾器。我們可以將它理解為一個含有參數(shù)的閉包铅乡。當我們使用@use_logging(level="warn")
調(diào)用時继谚。可以解釋器可以發(fā)現(xiàn)這一層封裝阵幸,并把參數(shù)傳遞到裝飾器的環(huán)境中花履。
part3 內(nèi)置裝飾器
內(nèi)置裝飾器主要有三個 @staticmathod、 @classmethod挚赊、 @property诡壁。
對于前兩者:
- 兩者的區(qū)別在于@classmethod的第一個參數(shù)會默認為calculations這個類。
而@property的作用主要是提供一個把類方法變成類屬性的方法荠割。
比如可以把@property用作getter和setter妹卿。
以上,是簡單的總結(jié)蔑鹦。
參考資料: