装饰器
-
定义:
假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
-
无参数装饰
#原函数
def now():
print ('2013-12-25')
#定义装饰的方法
def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
# 装饰函数
@log
def now():
print '2013-12-25'
#测试结果
>>> now()
call now():
2013-12-25
原理:由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。
-
有参数装饰:
@log(*args)
#两层装饰,外部的接受参数,内部的接受函数
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
#被包装的函数
@lzy('lzy')
def name():
print 'name'
#结果
name()
lzy is the beauty name
name
在调用该函数的包装方法里,要使用Python内置的functools.wraps
,防止有些依赖函数签名的代码执行出错。
-
偏函数
functools.partial:创建一个偏函数 functtools.partial(f,defaultX=x),创建出的是一个新的函数
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85