装饰器:
1 def w1(func): 2 def inner(): 3 # 验证1 4 # 验证2 5 # 验证3 6 return func() 7 return inner 8 9 @w1 10 def f1(): 11 print 'f1'
如上例@w1,@函数名 是python的一种语法糖。作用是:
-
- 执行w1函数,并将 @w1 下面的 函数 作为w1函数的参数,即:@w1 等价于 w1(f1)
所以,内部就会去执行:
def inner:
#验证
return f1() # func是参数,此时 func 等于 f1
return inner # 返回的 inner,inner代表的是函数,非执行函数
其实就是将原来的 f1 函数塞进另外一个函数中 - 将执行完的 w1 函数返回值赋值给@w1下面的函数的函数名
w1函数的返回值是:
def inner:
#验证
return 原来f1() # 此处的 f1 表示原来的f1函数
然后,将此返回值再重新赋值给 f1,即:
新f1 = def inner:
#验证
return 原来f1()
- 执行w1函数,并将 @w1 下面的 函数 作为w1函数的参数,即:@w1 等价于 w1(f1)
总而言之:@w1 等价于f1=w1(f1)
有参装饰器
1 def auth(driver='file'): 2 def auth2(func): 3 def wrapper(*args,**kwargs): 4 name=input("user: ") 5 pwd=input("pwd: ") 6 7 if driver == 'file': 8 if name == 'egon' and pwd == '123': 9 print('login successful') 10 res=func(*args,**kwargs) 11 return res 12 elif driver == 'ldap': 13 print('ldap') 14 return wrapper 15 return auth2 16 17 @auth(driver='file') 18 def foo(name): 19 print(name) 20 21 foo('egon') 22 23 #就是在普通装饰器前面再加一层
装饰器补充:wraps
functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module__、__name__、__doc__,或者通过参数选择。代码如下
1 from functools import wraps 2 3 def deco(func): 4 @wraps(func) #加在最内层函数正上方 5 def wrapper(*args,**kwargs): 6 return func(*args,**kwargs) 7 return wrapper 8 9 @deco 10 def index(): 11 '''哈哈哈哈''' 12 print('from index') 13 14 print(index.__doc__)