裝飾器
-
定義:
假設(shè)我們要增強(qiáng)now()函數(shù)的功能武翎,比如,在函數(shù)調(diào)用前后自動(dòng)打印日志,但又不希望修改now()函數(shù)的定義枝誊,這種在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式,稱之為“裝飾器”(Decorator)惜纸。
-
無(wú)參數(shù)裝飾
#原函數(shù)
def now():
print ('2013-12-25')
#定義裝飾的方法
def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
# 裝飾函數(shù)
@log
def now():
print '2013-12-25'
#測(cè)試結(jié)果
>>> now()
call now():
2013-12-25
原理:由于log()是一個(gè)decorator叶撒,返回一個(gè)函數(shù)绝骚,所以,原來(lái)的now()函數(shù)仍然存在痊乾,只是現(xiàn)在同名的now變量指向了新的函數(shù)皮壁,于是調(diào)用now()將執(zhí)行新函數(shù),即在log()函數(shù)中返回的wrapper()函數(shù)哪审。wrapper()函數(shù)的參數(shù)定義是(*args, **kw)蛾魄,因此,wrapper()函數(shù)可以接受任意參數(shù)的調(diào)用湿滓。在wrapper()函數(shù)內(nèi)滴须,首先打印日志,再緊接著調(diào)用原始函數(shù)叽奥。
-
有參數(shù)裝飾:
@log(*args)
#兩層裝飾扔水,外部的接受參數(shù),內(nèi)部的接受函數(shù)
def log(*args):
def fun(fun):
def lzy(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print '%s is the beauty %s' % (text,func.__name__)
return func(*args,**kw)
return wrapper
return decorator
#被包裝的函數(shù)
@lzy('lzy')
def name():
print 'name'
#結(jié)果
name()
lzy is the beauty name
name
在調(diào)用該函數(shù)的包裝方法里朝氓,要使用Python內(nèi)置的functools.wraps
,防止有些依賴函數(shù)簽名的代碼執(zhí)行出錯(cuò)魔市。
-
偏函數(shù)
functools.partial:創(chuàng)建一個(gè)偏函數(shù) functtools.partial(f,defaultX=x),創(chuàng)建出的是一個(gè)新的函數(shù)
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85