#装饰器
#装饰器的形成过程:最简单的装饰器,有返回值的,有一个参数,万能参数
#装饰器的作用---在不修改函数的调用方式,但是还想在原来的函数前后添加功能
#原则:开放封闭原则
# 开放
#对扩张是开放的,即在已有功能的环境下,新增更多的功能
#封闭
#对修改是封闭的,即已经封板的程序不能再修改
# 语法糖 @装饰器的函数名,同时改语法糖紧接着下行就是被装饰的函数
#装饰器的固定模式
# import time # 导入解释器的时间模块
#
# def run_time(a): # 装饰器函数 # 计算某个函数执行的时间
# def run_time1():
# start = time.time() # 获取当前时间
# a() # 被装饰的函数
# end = time.time()
# print(end - start)
# return run_time1
#
# @run_time # 语法糖 @装饰器函数名 该语句相当于 func = run_time(func) func只是一个变量名,可以为其他字符
# def func(): # 被装饰的函数
# time.sleep(1) # 让程序在执行到这个位置的时候停多少秒
# print('你好我好大家好!')
#
# #func = run_time(func)
# func()
#run_time就是一个装饰器函数,只是对一个函数有一些装饰作用
# import time # 导入解释器的时间模块
#
# def run_time(a): # 装饰器函数 # 计算某个函数执行的时间
# def run_time1():
# start = time.time() # 获取当前时间
# ret = a() # 被装饰的函数
# end = time.time()
# print(end - start)
# return ret
# return run_time1
#
# @run_time # 语法糖 @装饰器函数名 该语句相当于 func = run_time(func) func只是一个变量名,可以为其他字符
# def func(): # 被装饰的函数
# time.sleep(1) # 让程序在执行到这个位置的时候停多少秒
# print('你好我好大家好!')
# return '新年好'
# #func = run_time(func)
# ret = func()
# print(ret)
# # 装饰带参数函数的装饰器
# import time # 导入解释器的时间模块
#
# def run_time(f): # 装饰器函数 # 计算某个函数执行的时间
# def run_time1(*args,**kwargs):
# start = time.time() # 获取当前时间
# ret = f(*args,**kwargs) # 被装饰的函数
# end = time.time()
# print(end - start)
# return ret
# return run_time1
#
# @run_time # 语法糖 @装饰器函数名 该语句相当于 func = run_time(func) func只是一个变量名,可以为其他字符
# def func(a,b): # 被装饰的函数
# time.sleep(0.01) # 让程序在执行到这个位置的时候停多少秒
# print('你好我好大家好!',a,b)
# return '新年好'
# #func = run_time(func)
# #带一个参数的
# # ret = func(1)
# #带多个参数的 将参数改为*args
# # ret = func(1,2,3)
# #万能参数 将参数改为*args,**kwargs
# ret = func(1,b=100)
# print(ret)
# 装饰器的固定格式
# import time # 导入解释器的时间模块
#
# def wrapper(f): # 装饰器函数 f被装饰的函数
# def inner(*args,**kwargs):
# ret = f(*args,**kwargs) # 被装饰的函数
# return ret
# return inner
#
# @wrapper # 语法糖 @装饰器函数名 该语句相当于 func = run_time(func) func只是一个变量名,可以为其他字符
# def func(a,b): # 被装饰的函数
# time.sleep(0.01) # 让程序在执行到这个位置的时候停多少秒
# print('你好我好大家好!',a,b)
# return '新年好'
# 装饰器的进阶
# 函数最多嵌套三层
#带参数的装饰器
#假如你有300个参数,计算运行时间
#初始版本
# import time
# def timmer(func):
# def inner(*args,**kwargs):
#
# start = time.time()
# ret = func(*args,**kwargs)
# end = time.time()
# print(end - start)
# return ret
#
# return inner
#
# @timmer
# def test():
# time.sleep(0.1)
# @timmer
# def test1():
# time.sleep(0.1)
#
# test()
# test1()
#进阶版本,带参数
# import time
# FLAG = True
# def timmer_out(flag):
# def timmer(func):
# def inner(*args,**kwargs):
# if flag:
# start = time.time()
# ret = func(*args,**kwargs)
# end = time.time()
# print(end - start)
# return ret
# else:
# ret = func(*args,**kwargs)
# return ret
# return inner
# return timmer
#
# @timmer_out(FLAG) # 因为加了括号 所以先执行timmer_out()函数,该函数运行后返回timmer,即@timmer了
# #@timmer_out(FLAG)
# #timmer = timmer_out(FLAG)
# #@timmer
# def test():
# time.sleep(0.1)
# @timmer_out(FLAG)
# def test1():
# time.sleep(0.1)
#
# test()
# test1()
# 多个装饰器装饰一个函数
# 注意语法糖的运行顺序,可以通过Debug模式观察
# def wrapper1(func): # func --> f
# def inner1():
# print('这是第一个函数的前一句')
# ret = func() # f()
# print('这是第一个函数的后一句')
# return ret
# return inner1
#
# def wrapper2(func): # func --> inner1
# def inner2():
# print('这是第二个函数的前一句')
# ret = func() # inner1()
# print('这是第二个函数的后一句')
# return ret
# return inner2
#
# # 根据语法糖的规则,@wrapper2 下层没有函数,无法执行,@wrapper1下层有函数,就优先执行@wrapper1
# @wrapper2 # f = wrapper2(f) =wrpper2(inner)== inner2 因为已经执行了wrapper1 f已经赋值返回inner1
# @wrapper1 # f = wrapper1(f) == inner1
# def f():
# print('这是被装饰的函数')
# return "哈哈哈"
#
# ret = f() # inner2()
# print(ret)
#常用地方
#记录用户的登陆情况
#计算这个函数的运行时间