decorator本质上是一个高阶函数,它接受一个函数作为参数,返回一个新函数,实现了增强原函数的功能。
无参数decorator:
以log函数为例
def log(f):
def fn(*args, **kw):
print 'call ' + f.__name__ + '()...' #f.__name__表示函数名称
return f(*args, **kw) #保证任意个数的参数总是能正常调用
return fn
调用log来修饰函数add
@log
def add(x, y):
return x + y
带参数decorator:
多定义一层函数即可
def log(prefix):
def log_decorator(f):
def wrapper(*args, **kw):
print '[%s] %s()...' % (prefix, f.__name__)
return f(*args, **kw)
return wrapper
return log_decorator
@log('DEBUG')
def test():
pass
print test() #结果为[DEBUG] test()...
完善decorator:
def log(f):
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper
@log
def f2(x):
pass
print f2.__name__
上面这种情况下,打印结果不是‘f2’,而是‘wrapper’
这时需要用Python内置的functools来完成函数属性的复制
import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper
需要注意的是,函数的参数名不一定能复制
偏函数:functools.partial() 用来给一个多参数函数提供一部分参数,减少参数个数,简化调用
比如给int()函数提供参数2,得到新的二进制转换函数int2
import functools
int2 = functools.partial(int, base=2)
print int2('1000000')
print int2('1010101')