概述
裝飾器本質上是乙個python函式,它可以讓其他函式在不需要做任何**變動的前提下增加額外功能,裝飾器的返回值也是乙個函式物件。
我們要需要乙個能測試函式執行時間的decorator,可以定義如下:
def timer(func):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("run time is: %s" % (end_time - start_time))
return res
因為它是乙個decorator,所以接受乙個函式作為引數,並返回乙個函式。我們要借助python的@語法,把decorator置於函式的定義處:
@timer
def fun():
time.sleep(1)
print("this is a test")
return "ok"
執行結果就是:
this is a test
run time is: 1.0000572204589844
ok把@timer放在fun()處就相當於執行了語句:
fun = timer(fun)
如果decorator本身需要傳入引數,那就需要編寫乙個返回decorator的高階函式,比如加上名字:
def timer(name):
def decorator(func):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("name is: %s ; run time is: %s" % (name, (end_time - start_time)))
return res
return decorator
呼叫及結果顯示如下:
@timer("lance#")
def fun():
time.sleep(1)
print("this is a test")
return "ok"
this is a test
name is: lance# ; run time is: 1.0000572204589844
ok和兩層巢狀的decorator相比,三層巢狀的效果是這樣的:
fun = timer("lance#")(fun)
因為函式也是物件,它也有__name__等屬性。
python內建的functools.wraps就可以完成這個任務,所以,乙個完整的decorator的寫法如下:
import functools
def timer(func):
@functools.wraps(func)
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("run time is: %s" % (end_time - start_time))
return res
整體**如下:
__author__ = "lance#"
# -*- coding = utf-8 -*-
import time
import functools
def timer(name):
def decorator(func):
@functools.wraps(func)
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("name is: %s ; run time is: %s" % (name, (end_time - start_time)))
return res
return decorator
@timer("lance#")
def fun():
time.sleep(1)
print("this is a test")
return "ok"
if __name__ == '__main__':
print(fun())
Python裝飾器的分析
裝飾器模式 decorator pattern 允許向乙個現有的物件新增新的功能,同時又不改變其結構。計時器裝飾器 deffn timer function import time deffunction timer args,kwargs t0 time.time result function ...
python裝飾器 Python 裝飾器
簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...
python裝飾器 裝飾器
由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now 現在,假設我們要增強now 函式的...