""""
装饰器:本质是函数,为其他函数添加附加功能
原则:不修改被修改的函数的源代码
不修改被装饰的函数的调用方式
使用方式:高阶函数 + 函数嵌套 + 闭包
高阶函数:函数的接收的参数是一个函数名
函数的返回值是一个函数名
"""
# 例题:装饰器使用
# import time
# def timmer(func): #高阶函数,参数是函数名,用于传需要装饰的函数
# def wra(*args,**kwargs): #函数嵌套,参数用*,**保证能传任意参数,且怎么传过来就传回去
# start_time = time.time()
# res = func(*args,**kwargs)#闭包:每一个嵌套相当于一个包,类似作用域,能调用外层变量
# stop_time = time.time()
# print("函数运行时间%s" %(stop_time - start_time))
# return res #给被装饰的函数一个返回值,注意返回值是与函数放在同一层级
# return wra
# @timmer #@相当于f = tiemer(f)
# def f(n):
# s = 0
# for i in range(n):
# time.sleep(0.1)
# s += i
# return s #必须在装饰器中给定这个函数的return,这个函数才会有返回值
# ret = f(10)
# print(ret)
"""
装饰器框架:
def f(func): #高阶函数,参数是函数名,用于传需要装饰的函数
def s(*args,**kwargs): #嵌套函数,使用*,**接收任意参数,接收的是被修饰的函数的参数,注意怎么接收就怎么传回去
res = func(*args,**kwargs) #闭包,调用外层的变量。这个地方的参数*,**是调用外层嵌套函数获得的参数
return res #给被装饰的函数一个返回值,注意这个return是放在装饰器中,与函数调用放在同一层级,放在被装饰函数中不会生成返回值
return s #返回嵌套函数
@f #执行test = f(test),保证函数调用方式不变
def test(): #需要装饰的函数
"""
#设置一个网站认证
name_list = [
{"name":"sjy","word":"123"}, #相当于一个数据库,可open文件打开数据
{"name":"yue","word":"111"}, #用户名和密码是字符串,若在用户输入时做int转换,则就变成数字
{"name":"yi","word":"222"} #注意用户输入的类型,一般是以字符串形式
]
username_passwd = {"name":None,"login":False} #定义一个全局变量来作为初始值
def atu_ty(atu_type="ldap"): #想装饰器能够调用参数,则利用闭包,把装饰器嵌套到一个函数中
def atu(func):
def war(*args,**kwargs):
if atu_type == "ldap": #判断认证类型
print("type is", atu_type)
if username_passwd["name"] and username_passwd["login"]: #先判断初始值是否为True
res = func(*args,**kwargs) #当True时直接运行,跳过重新输入
return res
username = input("name:")
passwd = input("password:") #这里输入的是字符串
for i in name_list:
if username == i["name"] and passwd == i["word"]: #做一个输入结果的认证判断
username_passwd["name"] = username #将符合的结果更新到初始值,保留,再调用时不用再重新输入
username_passwd["login"] = True
res = func(*args,**kwargs)
return res
else: #此时else是在for循环用户列表结束后,都没有符合时再判否,若放在for循环内,只会判断其中一次是否符合
print("username or password of error")
war()
elif atu_type == "filedb": #其他的类型方式认证
...
print("type is %s" %atu_type)
res = func(*args, **kwargs)
return res
else:
...
print("unknown type")
res = func(*args, **kwargs)
return res
return war
return atu #装饰器嵌套在一个函数中,需返回函数,才能将装饰器调用起来
@atu_ty(atu_type="ldap") #运行atu_ty函数,内部返回的值就是atu函数,就是在调用装饰器
def index():
print("欢迎")
@atu_ty(atu_type="filedb") #用不同类型进行认证
def shop():
print("商品")
@atu_ty(atu_type="ss")
def pay():
print("付款")
index()
shop()
pay()