多层装饰器,有参装饰器,递归算法,三元表达式
今日概要
-
多层装饰器
-
有参装饰器(偷梁换柱你懂吗)
-
递归函数
-
算法(二分法)
-
三元表达式
1.多层装饰器(代码以及流程)
# 语法糖会将紧挨着的被装饰对象的名字当做参数自动传入装饰器函数中
def outer1(func1): #第十一步 执行outer1(func1)(此时outer1(func1)已经变成outer1(wrapper2))
# 注: func1是wrapper2
print('加载了outer1') ##第十二步 打印 '加载了outer1' 注:执行完这一步就会继续往下执行 ↓
def wrapper1(*args, **kwargs): # 第十五步执行wrapper1()
print('执行了wrapper1') #第十六步 打印'执行了wrapper1'
res1 = func1(*args, **kwargs) #第十七步 先执行等号右边的(func1就是wrapper2)所以res1接收的就是wrapper2()
return res1
return wrapper1 #第十三步 返回wrapper1 返回的wrapper1变为 index = wrapper1 = outer1(wapper2)
#为什么是index (因为语法糖原则见:44行注释)
def outer2(func2): #第七步 执行outer2(func2)(此时outer2(func2)已经变成outer2(wrapper3))
# 注: func2是wrapper3
print('加载了outer2') #第八步 打印 '加载了outer2'
def wrapper2(*args,**kwargs): # 第十八步执行wrapper2()
print('执行了wrapper2') #第十九步 打印'执行了wrapper2'
res2 = func2(*args, **kwargs) #第二十步 先执行等号右边的(func2就是wrapper3)所以res2接收的就是wrapper3()
return res2
return wrapper2 #第九步 返回wrapper2 返回的wrapper2变为 wrapper2 = outer2(wapper3)
def outer3(func3): #第三步 执行outer3(func3)(此时outer(func1)已经变成outer3(index))
#注: func3才是真正的index
print('加载了outer3') #第四步 打印 '加载了outer3'
def wrapper3(*args, **kwargs): # 第二十一步执行wrapper3()
print('执行了warpper3') #第二十二步 打印'执行了wrapper3'
res3 = func3(*args, **kwargs) #第二十三步 先执行等号右边的(func3就是index)所以res3接收的就是index(),随后执行index()
return res3
return wrapper3 #第五步 返回wrapper3 返回的wrapper3变为 wrapper3 = out3(index)
@outer1 # 第十步 xxx = outer1(wrapper2) index = outer1(wrapper2) {要先执行右边的outer1(wrapper1)}
# ↑ 语法糖原则:遇到最后一个才会使用相同的变量名传给装饰器函数使用
@outer2 # 第六步 xxx = outer2(wrapper3) wrapper2 = outer2(wrapper3) {要先执行右边的outer1(wrapper3)}
@outer3 # 第二步 xxx = outer3(index) wrapper3 = outer3(index) {要先执行右边的outer3(index)}
def index(): #第一步
print('from index') #第二十四步 打印‘from index’
index() #第十四步 调用index() 此时index是wrapper1 (所以要执行的就是wrapper1())
# 多层语法糖解读顺序是先看语法糖有几个,然后再由下往上去看,遇到最后一个才会使用相同的变量名传给装饰器函数使用
# 语法糖三:wrapper3 = outer3(index),加载了outer3
# 语法糖二:wrapper2 = outer2(wrapper3),加载了outer2
# 语法糖一;index = outer1(wrapper2),加载了outer1
# 执行顺序就是:wrapper1>>>>>wrapper2>>>>>wrapper3
# 加载outer3>>>加载outer2>>>加载outer1>>>index()>>>运行wrapper1函数体代码
# >>>然后再执行outer2函数体代码>>>然后再执行wrapper3的函数体代码
#注意:当等号右边是一个函数时,要先执行右边的函数
3.递归函数
何为递归函数?
函数直接或者间接调用自身,这就是递归函数。(递归函数一定要有边界)
递归调用:直接调用
# def index():
# print('from index')
# index()
# index()
# 递归调用:间接调用
# def index():
# print('from index')
# func()
# def func():
# print('from func')
# index()
# func()
#print(sys.getrecursionlimit()) # 1000 获取递归最大次数
#sys.getrecursionlimit()此方法返回python解释器的递归限制的当前值。
# sys.setrecursionlimit(2000) 自定义最大次数
# print(sys.getrecursionlimit())
4.算法(二分法)
什么是算法
算法就是解决问题的方法
二分法
是所有算法里面最简单的算法
二分法步骤
添加递归函数的结束条件
1.先获取数据集中间那个数
2.判断中间的数据值与目标数据值孰大孰小
3.说明要查找的数在数据集右半边 如何截取右半边
3.1.获取右半边中间那个数
3.2.与目标数据值对比
3.3.根据大小切割数据集
经过分析得知 应该使用递归函数
4.说明要查找的数在数据集左半边 如何截取左半边
4.1.获取左半边中间那个数
4.2.与目标数据值对比
4.3.根据大小切割数据集
经过分析得知 应该使用递归函数
二分法缺陷
1.数据集必须是有序的
2.查找的数如果在开头或者结尾 那么二分法效率更低!!!