python装饰器
定义了一个函数,想在运行时动态增加功能,又不想改动函数本身的代码,这就是所谓的装饰器
例如:
希望对下列函数调用增加log功能,打印出函数调用:
def f1(x): return x*2 def f2(): return x*x def f3(): return x*x*x
第一种方法,直接修改原函数:
def f1(x): print 'call f1()'
return x*2 def f2(): print'call f2()' return x*x def f3(): print 'cal f3()' return x*x*x
第二种方法,利用高阶函数:
def f1(x): return x*2 def new_fn(f):#装饰器函数 def fn(x): print 'call' +f.__name__+'()' #__name__为函数对象的属性 return f(x) return fn
那我们如何调用装饰器了
第一种方法:
g1 = new_fn(f1) print g1(5)
第二种方法,f1的原始定义函数被隐藏:
f1 =new_fn(f1) print f1(5)
python内置的@语法就是为了简化装饰器调用:
@new_fn def f1(x): return x*2
这段的代码就相对于是如下的代码的简写:
首先定义f1函数,然后通过new_fn这个高阶函数返回了一个新的函数并且这个新的函数并赋值给了f1,原有的f1函数就被彻底的隐藏。
def f1(x): return x*2 f1 = new_fn(f1)
装饰器可以极大的简化代码,避免每个函数编写重复性代码,并且装饰器可以打印日志:@long,检查性能:@performance,数据事务:@transaction,url路由:@post('/register')
完整示例:
def deco(func): def _deco(*args, **kwargs): print("before %s called." % func.__name__) ret = func(*args, **kwargs) print(" after %s called. result: %s" % (func.__name__, ret)) return ret return _deco @deco def myfunc(a, b): print(" myfunc(%s,%s) called." % (a, b)) return a+b @deco def myfunc2(a, b, c): print(" myfunc2(%s,%s,%s) called." % (a, b, c)) return a+b+c myfunc(1, 2) myfunc(3, 4) myfunc2(1, 2, 3) myfunc2(3, 4, 5)
结果:
before myfunc called. myfunc(1,2) called. after myfunc called. result: 3 before myfunc called. myfunc(3,4) called. after myfunc called. result: 7 before myfunc2 called. myfunc2(1,2,3) called. after myfunc2 called. result: 6 before myfunc2 called. myfunc2(3,4,5) called. after myfunc2 called. result: 12