注意:解决缩进问题用tab键(不用空格)
基础:
# -*- coding:utf-8 -*-
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
# print 'begin call'
print 'call %s():' % func.__name__
func(*args, **kw) #等同于 return func(*args,**kw)
# print 'end call'
return wrapper
@log
#这句@语法务必置于函数的定义处
#相当于执行 now=log(now),执行完后,now指向log(now)的返回值,即wrapper函数
#如果此时print now,得到wrapper函数(如 print now.__name__,会得到'wrapper')
#这也是用@functools.wraps(func)的原因,这个函数可以使得函数名不变,仍为now
#此后调用now(),就相当于执行wrapper函数,如 print now()
#以上用到了函数的返回值的知识点。
def now(name):
print '2015-05-13',name
print now('rain')
print now.__name__
练习:写出一个@log
的decorator,使它既支持:
@log
def f():
pass
又支持:
@log('execute')
def f():
pass
解析:
@log形式,相当于调用:
fn = log(fn)
@log('arg')形式,相当于调用:
fn = log('arg')(fn)
使用函数:callable()
判断一个对象是否是函数
代码如下:
# -*- coding:utf-8 -*-
import functools
def log(arg):
if callable(arg):
# @log 模式
func = arg
@functools.wraps(func)
def wrapper(*args, **kw):
print 'call %s():' %func.__name__
func(*args,**kw)
return wrapper
else:
# @log('arg') 模式:
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print '%s %s():' %(arg,func.__name__)
func(*args,**kw)
return wrapper
return decorator
@log
def now():
print '2015-05-13'
@log('execute')
def next():
print '2015-05-13'
print now()
print next()