def document_it(func): def new_function(*args, **kwargs): print('Running function:', func.__name__) print('Positional arguments:', args) print('Keyword arguments:', kwargs) result = func(*args, **kwargs) print('Result:', result) return result return new_function #def add_ints(a, b): # return a + b #cooler_add_ints = document_it(add_ints) #cooler_add_ints(3, 5) #('Running function:', 'add_ints') #('Positional arguments:', (3, 5)) #('Keyword arguments:', {}) #('Result:', 8) #@document_it #def add_ints(a, b): # return a + b #add_ints(3, 5) def square_it(func): def new_function(*args, **kwargs): result = func(*args, **kwargs) return result * result return new_function #@square_it #@document_it #def add_ints(a, b): # return a + b #add_ints(3, 5) #('Running function:', 'add_ints') #('Positional arguments:', (3, 5)) #('Keyword arguments:', {}) #('Result:', 8) @document_it @square_it def add_ints(a, b): return a + b add_ints(3, 5) #('Running function:', 'new_function') #('Positional arguments:', (3, 5)) #('Keyword arguments:', {}) #('Result:', 64) #靠近函数定义的装饰器最先执行
def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper @log def now(): print('2015-3-25') now() #call now(): #2015-3-25
如果decorator本身需要传入参数
def log(text): def decorator(func): def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator @log('execute') def now(): print('2015-3-25') now() print(now.__name__) #execute now(): #2015-3-25 #wrapper
不需要编写wrapper.__name__ = func.__name__
这样的代码,Python内置的functools.wraps
就是干这个事的
相当于:
now = log(now)
now = log('execute')(now)