python基础18-多层装饰器-有参装饰器-递归调用-二分法
今日学习
多层装饰器
有参装饰器
递归函数
算法(二分法)
多层装饰器
总结
语法糖从下到上,执行流程从上到下
def outter1(func1):
print('加载了outter1')
def wrapper1(*args, **kwargs):
print('执行了wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def outter2(func2):
print('加载了outter2')
def wrapper2(*args, **kwargs):
print('执行了wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def outter3(func3):
print('加载了outter3')
def wrapper3(*args, **kwargs):
print('执行了wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3
@outter1
@outter2
@outter3
def index():
print('from index')
有参装饰器
直接在装饰器上层添加一层闭包函数用于传参
def login_auth(func_name):
def inner(*args, **kwargs):
username = input('username>>>:').strip()
password = input('password>>>:').strip()
if username == 'jason' and password == '123':
res = func_name(*args, **kwargs)
return res
else:
print('用户权限不够,无法调用函数')
return
"""
需求
#需要再装饰器内部可以切换多种数据来源
列表
字典
文件
"""
def outter(condition,type_user):
def login_auth(func_name): #这里不能再填写其他形参
def inner(*args, **kwargs): #不能填写非被装饰所需的参数
username = input('username>>>:').strip()
password = input('password>>>:').strip()
#根据用户需求执行不同的代码
if type_user =='jason':print('vip')
if condition == '列表':
print('使用列表作为数据来源,比对用户数据')
elif condition == '字典':
print('使用字典作为数据来源,比对用户数据')
elif condition == '文件':
print('使用文件作为数据来源,比对用户数据')
else:
print('不好意思,我目前只有上面几种方式')
return inner
return login_auth
@outter('字典','jason')
def index():
print('from index')
index()
递归
-
直接递归调用
-
函数直接调用了自己
def index(): print('from index') index() index()
-
间接递归调用
def index(): print('调用了index') func() def func(): print('调用了func') index() func() 1.定义了index函数,func函数,先调用了func函数,后func函数代码块里再调用了index函数体/ ---------执行结果----------- 调用了func 调用了index 调用了func
-
递归函数真正的应用
递归- 一层一层的往下寻找答案 回溯- 根据一直条件推导最终结果 每次调用的时候都必须要比上一次简单 并且递归函数要有明确的结束条件!!! --------------------------题目:#循环打印出列表中所有的数字------------------- l1 = [1,[2,[3,[4,[5,[6]]]]]] 思路: #1.for 循环l1里面所有的数据值 #2.判断当前数据值是否是数字,如果是则打印 #3.如果不是则继续for循环里面所有的数据值 #4.判断当前数据值是否是数字,如果是则打印 #5.如果不是则继续for循环里面的所有数据值 #6.判断当前数据值是否是数字,如果是则打印 l1 = [1,[2,[3,[4,[5,[6]]]]]] for i in l1: if isinstance(i,int): print(i) else: for j in i: if isinstance(j,int): print(j) else: for k in j: if isinstance(k,int): print(k) ----------------执行结果---------- - 1 2 3 ... 此时我还没取完,代码写累了。如何巧妙的处理这种事情呢 -----------------正确代码---------------------- l1 = [1,[2,[3,[4,[5,[6]]]]]] def get_num(l1): for i in l1: if isinstance(i,int): print(i) else: get_num(i) get_num(l1) -----------执行结果--------------- 1 2 3 4 5 6 -------执行取值完成了所有的------------
算法
-
二分法
采用二分法查找时,数据需是排好序的。 基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。
-
缺陷
1.数据集必须是有序的 2.查找的数如果在开头或者结尾 那么二分法效率更低!!!
-
例
l1 = [11, 23, 32, 45, 65, 78, 90, 123, 432, 467, 567, 687, 765, 876, 999, 1131, 1232] def get_num(l1,target_num): #添加递归函数的结束条件 if len(l1) == 0: print('不好意思,找不到') return # #1.先获取数据中间的哪个数 middle_index = len(l1) // 2 middle_value = l1[middle_index] # 2.判断中间的数据值与目标数据值数谁大谁小 if target_num >middle_value: right_l1 = l1[middle_index + 1:] # 3.1.获取右半边中间那个数 # 3.2.与目标数据值对比 # 3.3.根据大小切割数据集 # 经过分析得知 应该使用递归函数 print(right_l1) get_num(right_l1,target_num) elif target_num < middle_value: left_l1 = l1[:middle_index] # 4.1.获取左半边中间那个数 # 4.2.与目标数据值对比 # 4.3.根据大小切割数据集 # 经过分析得知 应该使用递归函数 print(left_l1) get_num(left_l1,target_num) get_num(l1,1000)
-
今日总结
1.原理较少,多层装饰器的执行原理是,多个语法糖执行流程是从下到上,装饰器的顺序是从上倒下。
2.有参装饰器就是在装饰器的基础上再封装一次函数,进行形参赋值。
def outter(condition,type_user):
def login_auth(func_name): #这里不能再填写其他形参
def inner(*args, **kwargs): #不能填写非被装饰所需的参数
3.递归分为直接调用和间接调用。
4.算法二分法,注意的点是,内容必须是排序好的;比较麻烦的是寻找的值在开头或者结尾