python装饰器
一、基本装饰器
#装饰函数 2 def decorator(foo): 3 def wrapper(): 4 print 'wrapper' 5 return foo() 6 return wrapper 7 8 #自定义函数 9 def abc(): 10 print 'abc' 11 12 #装饰abc 13 abc = decorator(abc)
调用abc()
输出:wrapper
abc
#装饰函数
def decorator(foo):
def wrapper():
print ('wrapper')
return foo()
return wrapper
@decorator
def abc():
print ('abc')
这种形式也能实现相同功能,加了语法糖@简化了形式,其过程就是执行@decorator之后将函数abc以参数形式进入decorator函数,执行函数体,函数体就是定义wrapper函数,所以这个时候不会有任何打印输出,只有再单独调用abc()的时候,才会都相应打印输出。
二、带参数的装饰器
这个参数指的是装饰器上的参数,也即@后面跟的函数的参数,带参数的装饰器外层需要再包一层函数。
def decrator(*dargs, **dkargs): def wrapper(func): def _wrapper(*args, **kargs): print "decrator param:", dargs, dkargs print "function param:", args, kargs return func(*args, **kargs) return _wrapper return wrapper @decrator(1, a=2) def foo(x, y=0): print "foo", x, y foo(3, y=4) # 输出: # decrator param: (1,) {'a': 2} # function param: (3,) {'y': 4} # foo 3 4
bottle.py中自动转换参数类型的装饰器:
def validate(**vkargs): def decorator(func): def wrapper(**kargs): for key in vkargs: # 根据vkargs中的参数的类型对kargs的参数进行类型转换 kargs[key] = vkargs[key](kargs[key]) return func(**kargs) return wrapper return decorator @validate(id=int, x=float, y=float) def move(id, x, y): print "move %d (%0.2f, %0.2f)"%(id, x, y) move(id="1", x="0.2", y="0.3")
三、@语法糖
import time def time(func): print('gundan') print(func()) @time def xxx(): print('Hello world!') return 10 输出: gundan Hello world! 10
如果多个@,自底向上调用开始,而且每一底层的@的输出作为上面@的参数带入进去,只有目标函数是最底部@的函数参数带入进去,如下:
def deco1(f): print ('decorate 1') print(f+1) def deco2(f): print ('decorate 2') return f()+1 @deco1 @deco2 def foo(): print ('hello') return 2
输出:
decorate 2 hello decorate 1 4
可以看出,foo以函数参数形式进入deco2,而deco2的返回值作为参数进入deco1,两者不一样。

浙公网安备 33010602011771号