# 储备知识:
# *args,**kwargs
# def index(x,y):
# print(x,y)
#
# def wrapper(*args,**kwargs): #args=(1,2,3,4,5) kwargs={'a':1,'b':2}
# index(*args,**kwargs) #index(*(1,2,3,4,5),**{'a':1,'b':2}
# #index(1,2,3,4,5,a=1,b=2)
#
# wrapper(1,2,3,4,5,a=1,b=2) #报错
# wrapper(y=222,x=111)
#1 名称空间与作用域:名称空间的嵌套关系是在函数嵌套阶段,即检测语法的时候确定的
#3 函数对象:
# 可以把函数当作参数传
# 可以把函数当作返回值传入
# def index():
# return 123
#
# def foo(func):
# return func
#
# foo(index)
#函数的嵌套定义
# def outter():
# def wrapper():
# pass
# return wrapper()
# 闭包函数
# def outter():
# x=11
# def wrapper():
# x
# print(x)
# return wrapper
# f=outter()
# f
#传参的方式一:通过参数的形式为函数体传值
# def outter(x):
# # x=1
# def wrapper(x):
# print(1)
# print(2)
# x
# return wrapper
#传参的方式二:通过闭包的方式式为函数体传值
# def outter(x):
# def wrapper():
# print(1)
# print(2)
# x
# return wrapper
# f=outter(1)
# f()
#二 装饰器
'''
1 什么是装饰器
器指的是工具,可以定义成函数
装饰:指的是为其他的事物添加额外功能点缀,
合到一起的解释:
指的是定义一个函数,该函数是用为其他函数增加功能
2 为何要用装饰器
开放封闭原则
开放:指的是对拓展功能是开放的
封闭:指的是对修改源代码是封闭的
应用程序
linux
硬件
装饰器就是在不修改被装饰对象源代码的以及调用方式的前提下为被装饰对象添加新功能
3 如何用装饰器
'''
#需求,在不修改index函数的源代码以及调用方式的前提下
# 为index添加新功能:统计时间
# def index(x,y):
# time.sleep(2)
# print('index %s %s'%(x,y))
#
# index(111,222)
#解决方案一:失败
#问题:没有修改背装饰对象的调用方式,但是修改了源代码
# import time
#
# def index(x,y):
# stat=time.time()
# time.sleep(2)
# print('index %s %s'%(x,y))
# stop=time.time()
#
# print(stop-stat)
#
# index(111,222)
#解决方案二:
#问题:没有修改被装饰对象的调用方式,也没有修改其源代码,并且加上了新功能
# import time
#
# def index(x,y):
# time.sleep(2)
# print('index %s %s'%(x,y))
#
# start=time.time()
# index(111,222)
# stop=time.time()
# print(stop-start)
#
# start=time.time()
# index(111,222)
# stop=time.time()
# print(stop-start)
#解决方案三:
#问题:解决了方案二的代码冗余的问题,但是改变了函数调用方式
# import time
#
# def index(x,y):
# time.sleep(2)
# print('index %s %s'%(x,y))
#
# def wrapper():
# start=time.time()
# index(111,222)
# stop=time.time()
# print(stop-start)
#
# wrapper()
# #方案三优化(1):将index()参数写活了
# import time
#
# def index(x,y,z):
# time.sleep(2)
# print('index %s %s %s'%(x,y,z))
#
# def wrapper(*args,**kwargs): #a=1 b=2
# start=time.time()
# index(*args,**kwargs)
# stop=time.time()
# print(stop-start)
#
# wrapper(1,2,3)
#方案三优化(2):将优化一的基础上将被装饰对象写活了
#原来只能装饰index
#被装饰对象是:index()
# import time
#
# def index(x,y,z):
# time.sleep(2)
# print('index %s %s %s'%(x,y,z))
# print(index)
#
# def home(name):
# time.sleep(2)
# print('welcome %s to home'%name)
#
# def outter(func):
# # func=index
# def wrapper(*args,**kwargs): #a=1 b=2
# start=time.time()
# func(*args,**kwargs) #index内存地址()
# stop=time.time()
# print(stop-start)
# return wrapper
#
#
# index=outter(index) #index=outter(index内存地址)
# #index = 当初那个wrapper函数的内存地址
# index(1,2,3) #运行index(),其实就是运行wrapper()
# print(index)
#
#
# #调用home
# home=outter(home) #index=wrapper的内存地址
# home('egon') #home=wrapper的内存地址
#方案三优化(3):将wrapper做的跟被装饰对象一模一样,以假乱真
#
# import time
#
# def index(x,y,z):
# time.sleep(2)
# print('index %s %s %s'%(x,y,z))
#
# def home(name):
# time.sleep(2)
# print('welcome %s to home'%name)
# return 123
#
# def outter(func):
# def wrapper(*args,**kwargs): #a=1 b=2
# start=time.time()
# res=func(*args,**kwargs) #index内存地址()
# stop=time.time()
# print(stop-start)
# return res
#
# return wrapper
# #偷梁换柱:home指向的是wrapper函数的内存地址
#
#
# home=outter(home)
#
# res=home('egon') #home=wrapper的内存地址
# print(res)
#解决方案四:如何在方案三的基础上不改变函数的调用方式
#语法糖:
# import time
#
# #装饰器
# def outter(func):
# def wrapper(*args,**kwargs): #a=1 b=2
# start=time.time()
# res=func(*args,**kwargs) #index内存地址()
# stop=time.time()
# print(stop-start)
# return res
#
# return wrapper
# #偷梁换柱:home指向的是wrapper函数的内存地址
#
# #在被装饰对象正上方单独一行写 @装饰器名字
# @outter #index=outter(index)
# def index(x,y,z):
# time.sleep(2)
# print('index %s %s %s'%(x,y,z))
#
# @outter #home=outter(home)
# def home(name):
# time.sleep(2)
# print('welcome %s to home'%name)
# return 123
#
#
#
#
#
# index(x=1,y=2,z=3)
# home('egon')
#思考题:叠加多个装饰器,加载顺序与运行顺序
# @deco1 #index=deco1(deco2.wrapperde内存地址)
# @deco2 #deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
# @deco1 #deco3.wrapper的内存地址=deco3(index)
# def index():
# pass
#总结:无参装饰器模板
# def outter(func):
# def wrapper(*args,**kwargs):
# #1 调用原函数
# #2 为其增加新功能
# res=func(*args,**kwargs)
# return res
# return wrapper
#
# @outter
# def index():
# print('from index')
#
# index()
def outter(func):
def wrapper(*args,**kwargs):
#1 调用原函数
#2 为其增加新功能
name=input('your name:').strip()
pwd=input('your password:').strip()
if name == 'egon' and pwd == '123':
res=func(*args,**kwargs)
else:
print('账号密码错误')
return wrapper
@outter
def index():
print('from index')
index()