带参装饰器
1.'''
未加来源认证的用户认证方法
import time
current_user={'user':None}
def deco(func):
def wrapper(*args,**kwargs):
if current_user['user']:
#已经登陆过
res = func(*args, **kwargs)
return res
user=input('username>>: ').strip()
pwd=input('password>>: ').strip()
if user == 'egon' and pwd == '123':
print('login successful')
# 记录用户登陆状态
current_user['user']=user
res=func(*args,**kwargs)
return res
else:
print('user or password error')
return wrapper
@deco
def index():
print('welcome to index page')
time.sleep(1)
@deco
def home(name):
print('welecome %s to home page' %name)
time.sleep(0.5)
index()
home('egon')
'''
'''
def f1():
x=1
def f2():
def f3():
print(x)
return f3
return f2
f2=f1()
f3=f2()
f3()
'''
2.带来源认证的有参函数
import time
current_user={'user':None} # 为None的时候是未登录状态,还没有用户存在
def auth(engine='file'):
def deco(func): # -->> 这里的形参是固定为被装饰对象的函数名,即传入的函数地址
def wrapper(*args,**kwargs): # -->> 这里的形参是固定给传入的被装饰对象使用的
if current_user['user']: # 如果是登陆状态,直接执行函数
#已经登陆过
res = func(*args, **kwargs)
return res # 获得返回值,没有返回值就返回None
user=input('username>>: ').strip() # 没登陆的话就让用户登录,输入用户名和密码
pwd=input('password>>: ').strip()
if engine == 'file': # 因为以后遇到的账户密码不一定只存放在文件里,还可能放在数据库,ldap等等里。
# 基于文件的认证
if user == 'egon' and pwd == '123': # 这里是没有打开文件直接进行对比
print('login successful')
# 记录用户登陆状态
current_user['user']=user # 把登陆的用户放在字典里,字典里不为None,表示用户已经登陆
res=func(*args,**kwargs)
return res
else:
print('user or password error')
elif engine == 'mysql': # 用户的多种认证存储认证方式
print('基于mysql的认证')
elif engine == 'ldap':
print('基于ldap的认证')
else:
print('无法识别认证来源')
return wrapper
return deco
# 总结: 装饰器带参数一般都是外面套着两层,第三层不是固定的形参,一般可以随意传参,没有限制。
@auth(engine='mysql') # @deco #index=deco(index) #index=wrapper
def index():
print('welcome to index page')
time.sleep(1)
@auth(engine='mysql') # auth传入实参并调用,获得返回值deco。deco获得被装饰对象传入的函数名,并且赋值给
def home(name): # 传入的函数名。被装饰对象把参数给wrapper,调用wrapper并执行。
print('welecome %s to home page' %name)
time.sleep(0.5)
index()
home('egon')
越是困难的事越要立即去做,这样收益才会最大!!!