def log(func): def wrapper(*args,**kw): print('call %s():'%func.__name__) return func(*args,**kw) return wrapper @log #相当于new=log(new) def now(): print('2015-3-25') now() call now(): 2015-3-25
由于log()
是一个decorator,返回一个函数,所以,原来的now()
函数仍然存在,只是现在同名的now
变量指向了新的函数,于是调用now()
将执行新函数,即在log()
函数中返回的wrapper()
函数。
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数
def log(t): def decorator(func): #参数是new()函数 def wrapper(*args,**kw): #传入now()的参数 print('%s %s():'%(t,func.__name__)) #打印now()函数的名字 return func(*args,**kw) #执行now()函数 return wrapper return decorator
@log('T') #相当于new=log('execute')(now)
def now():
print('2015-3-25')
首先执行log('execute')
,返回的是decorator
函数,再调用返回的函数,参数是now
函数,返回值最终是wrapper
函数。
要使函数new()的名称依然是'new'可以使用Python内置的
functools.wraps
import functools def log(t): def decorator(func): @functools.wraps(func) def wrapper(*args,**kw): print('%s %s():'%(t,func.__name__)) return func(*args,**kw) return wrapper return decorator @log('T') def now(x): print(x+1)