在python中常看到在定義函數(shù)是使用@func. 這就是裝飾器, 裝飾器是把一個函數(shù)作為參數(shù)的函數(shù),常常用于擴(kuò)展已有函數(shù),即不改變當(dāng)前函數(shù)狀態(tài)下增加功能.
def run(): print "I'm run."
我有這么一個函數(shù), 我想知道這個函數(shù)什么時候開始什么時候結(jié)束. 我應(yīng)該這么寫
def run(): print time.ctime() print "I'm run." print time.ctime()
但是如果不允許修改函數(shù)的話就需要裝飾器了
def count(func): def wrapper(): print time.ctime() ret = func() print time.ctime() return ret return wrapper@countdef run(): print "I'm run." # print '2015-4-10'
eg:
def now(): print '2015-4-10'f = nowf()
函數(shù)有一個__name__ 對象 可通過 dir(func) func為定義的函數(shù)名
now.__name__ # print 'now'f.__name__ # print 'now'print f # print '<function now at 0x000000000213A908>'print now # print '<function now at 0x000000000213A908>'
我們通過裝飾器打印log日志
def log(func): def wrapper(*args, **kwargs): print "call %s()" % func.__name__ return func(*args, **kwargs) return wrapper@logdef now(): print '2015-4-10'now() # print 'call now()'
其實裝飾器修飾函數(shù)相當(dāng)于, now = log(now) 也就是裝飾器函數(shù)把被修飾的函數(shù)當(dāng)參數(shù)后賦給同名的變量
functools.wraps 函數(shù)
當(dāng)我們使用了裝飾器后now的__name__值發(fā)生了改變
# 沒有使用前now.__name__ # print 'now'# 使用后now.__name__ # print 'wrapper'
當(dāng)我們使用裝飾器前,now.__name__使用的是當(dāng)前now函數(shù),但使用后 now這個函數(shù)其實是 log(now) 也就是log函數(shù)的返回值也就是被包裹的wrapper. 解決方法是functools.wraps函數(shù).
裝飾閉包, 使用前得調(diào)用 import functools
def log(func): @functools.wraps(func) def wrapper(*args, **kwargs): ...
帶參數(shù)的裝飾器
如果decorator需要傳入?yún)?shù), 那就需要在寫一個返回decorator的高階函數(shù). 寫出來更復(fù)雜.
def login(level): def _deco(func): def wrapper(*args, **kwargs): if level >= 5: print '用戶 VIP 等級 %d' % int(level-5) else: print '用戶 主站蜘蛛池模板: 中牟县| 海丰县| 秦安县| 鹤峰县| 平昌县| 临澧县| 荆州市| 克山县| 德格县| 河津市| 景宁| 安新县| 大同县| 枣强县| 天峻县| 吉首市| 讷河市| 宣化县| 大渡口区| 比如县| 崇明县| 六安市| 宝丰县| 辽中县| 岳池县| 合川市| 昆明市| 唐海县| 逊克县| 邳州市| 元氏县| 公安县| 万宁市| 绵阳市| 沁阳市| 洛阳市| 上高县| 潼南县| 镇远县| 景谷| 镶黄旗|