decorator的性质:
1.可以接收函数作为参数
2.可以返回函数
3.接收一个函数,对其进行包装,返回一个新的函数
A.无参数的decorator
#举例,包装f函数,打印f.__name__
def log(f):
def fn(x):
print 'call ' + f.__name__ + '()...'
return f(x)
return fn
@语法:用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。
#使用方法
@log
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
#call factorial()...
#3628800
B.带参数的decorator
带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数:
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()
C.functools
使用装饰器后,原来的函数名会被装饰器内定义的函数名覆盖,decorator还改变了函数的__doc__等其它属性。,所以对于那些依赖于函数名的代码块,一旦使用装饰器后,此类代码块就失效了,所以引入functools的概念
Python内置的functools可以用来自动化完成“复制”:
import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper