今日内容回顾7.7
今日内容回顾
多层装饰器
多层装饰器指的是将几个装饰器在不改变装饰对象原有的调用方式和内部代码的情况下同时装饰一个装饰对象上面来实现增加多种不同的功能。
def outter1(func1): # 7.func1= wrapper2 先调用outter1(wrapper2)加括号,括号内填入它下面的函数名,此时它下面是@outter2,@outter2的结果是wrapper2
print('我是outter1号') # 8.打印此代码
def wrapper1(*args, **kwargs):# 10.调用index相当于调用wrapper1 执行wrapper1
print('我是wrapper1号') # 11 打印此代码。
res1 = func1(*args, **kwargs) # 12.调用func1 此时的func1就是outter1里面的形参绑定的是outter2的返回值wrapper2 那么开始调用wrapper2
return res1 #9. 此时outter1的返回值是wrapper1,然后它上面没有语法糖了将用index来接收它的返回值。
return wrapper1
def outter2(func2): # 4.func2 = wrapper3 先调用outter2(wrapper3)加括号,括号内填入它下面的函数名,此时它下面是@outter3 @outter的结果是wrapper3
print('我是outter2号') # 5. 打印此代码
def wrapper2(*args, **kwargs): # 13.根据上面第11步的代码调用wrapper2,执行wrapper2
print('我是wrapper2号') # 14. 打印此代码
res2 = func2(*args, **kwargs) # 15.调用func2 此时的func2就是outter2里面的形参绑定的是outter3的返回值wrapper3 那么开始调用wrapper3
return res2 # 6.此时outter2的返回值是wrapper2,他的顶上还有一个语法糖@outter1
return wrapper2
def outter3(func3): # 1.func3=index 先调用outter3(index)加括号,括号内填入紧跟它下面的函数名index,将outter3的返回值赋值给变量名index。
print('我是outter3号') # 2.打印此代码
def wrapper3(*args, **kwargs): # 16.根据上面第14步开始调用wrpper3,执行wrpper3。
print('我是wrapper3号') # 17. 打印此代码
res3 = func3(*args, **kwargs) # 18.调用func3 此时的func3就是outter3里面的形参绑定的是真正的index 那么等于调用index
return res3
return wrapper3 # 3.此时outter3的返回值是wrapper3,那么顶上还有一个语法糖@outter2
#单层语法糖
@outter3 # @outter3 等同于 index = outter3(index)
def index():
print('from index')
index()
"""
语法糖功能
会自动将其下面紧挨着的函数名当作参数传递给@符号后面的函数名(加括号调用)
我是outter3号
我是wrapper3号
from index
"""
# 多层语法糖
@outter1 # (变量名index) = outter1(wrapper2)
@outter2 # wrapper2 = outter2(wrapper3)
@outter3 # wrapper3 = outter3(真正的函数名index)
def index(): # 19.调用 执行index
print('from index') # 20. 打印此代码
index()
"""
我是outter3号
我是outter2号
我是outter1号
我是wrapper1号
我是wrapper2号
我是wrapper3号
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 inner
"""
需求:在装饰器内部可以切换多种数据来源
列表
字典
文件
"""
def outer(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
@outer('文件','jason')
def index():
print('from index')
index()
"""
我们以后遇到的最复杂的装饰器就是上面的 不会比上面更复杂
目的仅仅是为了给装饰器代码传递更多额外的数据
"""
递归函数
递归函数的概念
函数直接或者间接调用了自己称之为递归调用
-
直接调用
在本体函数体代码内部添加一个本体函数名加括号来直接调用。
def index(): print('from index') index() index() # 这样会一直循环下去会 # 直到循环次数达到python解释器中的最大限制后报错,才停止!! -
间接调用
在俩个不同的函数体代码内部添加对方的函数名加括号来间接调用
def index(): print('from index') func() def func(): print('from func') index() func() # 这样也会一直循环下去会 # 直到循环次数达到python解释器中的最大限制后报错,才停止!! -
python中允许函数最大递归调用的次数
官方给出的限制是1000 用代码去验证可能会有些许偏差(997 998...)#示例1:自定义计算python中允许的限制次数 count = 1 def index(): print('from index') global count count += 1 # count = count + 1 print(count) index() index() # 示例2: import sys print(sys.getrecursionlimit()) # 1000 获取递归最大次数 sys.setrecursionlimit(2000) # 自定义最大次数 print(sys.getrecursionlimit())
递归函数真正的应用场景
递归函数
递推:一层层往下寻找答案
回溯:根据已知条件推导最终结果
-
每次调用的时候都必须要比上一次简单!!!
-
并且递归函数最终都必须要有一个明确的结束条件!!!
# 示例: l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]] # 循环打印出列表中所有的数字 # 1.for循环l1里面所有的数据值 # 2.判断当前数据值是否是数字 如果是则打印 # 3.如果不是则继续for循环里面所有数据值 # 4.判断当前数据值是否是数字 如果是则打印 # 5.如果不是则继续for循环里面所有数据值 # 6.判断当前数据值是否是数字 如果是则打印 def get_num(l1): for i in l1: if isinstance(i,int): print(i) else: get_num(i) get_num(l1)
算法之二分法
-
什么是算法
算法就是解决问题的方法
算法永远都在精进 但是很少有最完美的算法,算法很多时候可能没什么用
小公司一般不会有算法工程师 只有大公司才会有算法工程师待遇很高但是产出很少 甚至几年几十年都没有成果有点相当于科研人员
-
很多大型互联网面试都喜欢问算法
如:二分法、快排、 插入、 堆排、 链表、 双向链表、 约瑟夫问题 -
二分法
是所有算法里面最简单的算法,也有人说二分法不是算法
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: # 3.说明要查找的数在数据集右半边 如何截取右半边 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: # 4.说明要查找的数在数据集左半边 如何截取左半边 left_l1 = l1[:middle_index] # 4.1.获取左半边中间那个数 # 4.2.与目标数据值对比 # 4.3.根据大小切割数据集 # 经过分析得知 应该使用递归函数 print(left_l1) get_num(left_l1, target_num) else: print('找到了', target_num) # get_num(l1, 999) get_num(l1, 1000) """ 二分法缺陷 1.数据集必须是有序的 2.查找的数如果在开头或者结尾 那么二分法效率更低!!! """
作业
-
尝试编写有参函数将多种用户验证方式整合到其中
直接获取用户数据比对
数据来源于列表
数据来源于文件list1 = ['jason', '123', ] with open(r'user_info_data.txt','r',encoding='utf8')as f: file = f.read() def outer_def(data): def middle(xxx): def iner_layer(*args,**kwargs): name = input("username>>>>:") pwd = input("userpwd>>>>:") if data == list1: if name == list1[0] and pwd == list1[1]: print("校验成功!") a = xxx(*args,**kwargs) return a print("校验失败!") elif data == file: print(file) u = file.strip().split('|') print(u) if name == u[0] and pwd == u[1]: print("校验成功!") a = xxx(*args, **kwargs) return a print("校验失败") else: print("暂无此功能!") return iner_layer return middle @outer_def(data=file) def index(): print("我是index") index() -
尝试编写递归函数
推导指定某个人的正确年龄
eg: A B C D E 已知E是18 求A是多少def get_age(x): if x == 1: return 18 print((x-1)+2) return get_age(x-1)+2
print(get_age(5))

浙公网安备 33010602011771号