多层、有参装饰器、递归函数和算法之二分法
今日内容总结
一、给多个函数加上用户认证(代码)
二、多层装饰器
三、有参装饰器
四、递归函数
五、算法之二分法
一、给多个函数加上用户验证
要求:给多个函数加上用户认证功能
通过名和密码:'owen'、123
# 先定义一个装饰器
def login_auuth(func_name):
def inner(*args, **kwargs):
username = input('请输入用户名>>>:').strip()
password = input('请输入密码>>>:').strip()
if username == 'owen' and password == '123':
res = func_name(*args, **kwargs)
return res
else:
print('用户名或密码错误')
return inner
# 定义多个函数
#添加装饰器
@login_auuth
def index():
print('from index')
@login_auuth
def home():
print('from home')
@login_auuth
def func():
print('from func')
# 调用函数
index()
home()
func()
结果:
请输入用户名>>>:owen
请输入密码>>>:123
from index
请输入用户名>>>:owen
请输入密码>>>:123
from home
请输入用户名>>>:owen
请输入密码>>>:123
from func
二、使用一次验证,后面程序不再验证
# 默认用户没有输入
is_auth = {'is_login': False}
# 通过名和密码:'owen'、123
# 先定义一个装饰器模板
def login_auth(func_name):
def inner(*args, **kwargs):
if is_auth.get('is_login'):
res = func_name(*args, **kwargs)
return res
username = input('请输入用户名>>>:').strip()
password = input('请输入密码>>>:').strip()
if username == 'owen' and password == '123':
res = func_name(*args, **kwargs)
is_auth['is_login'] = True # 修改全局变量
return res
else:
print('用户名或密码错误')
return inner
@login_auth
def index():
print('from index')
@login_auth
def home():
print('from home')
@login_auth
def func():
print('from func')
# 调用函数
index()
home()
func()
结果:
请输入用户名>>>:owen
请输入密码>>>:123
from index
from home
from func
二、多层装饰器
# 语法糖会把紧挨着的装饰对象的名字当作参数自动传入装饰器函数中
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') # 第七步
# 调用
index()
# 加载了outter3
加载了outter2
加载了outter1
执行wrapper1
执行wrapper2
执行wrapper3
from index
三、有参装饰器
def outer(source_data):
def login_auth(func_name): # 只能接收一个被装饰对象名字
def inner(*args, **kwargs): # 只能用来给被装饰对象传参
username = input('请输入用户名>>>:').strip()
password = input('请输入密码>>>:').strip()
if source_data =='1':
print('使用字典方式处理数据')
elif source_data =='2':
print('使用列表方式处理数据')
elif source_data =='3':
print('使用文件操作处理数据')
else:
print('其他操作情况')
res = func_name(*args, **kwargs)
return res
return inner
return login_auth
# 函数名加括号,执行优先级最高
"""左边是语法糖结构,右侧是函数名加括号结构
先执行函数调用 outer('3') ,返回值是login_auth,然后执行语法糖@login_auth,
装饰器最多只能三层嵌套
from functools import wraps
@wraps(func_name)
"""
@outer('3')
def index():
print('from index')
四、递归函数
# 递归函数的本质:递归函数也称之为函数的递归,函数在运行过程中直接或者间接的调用了自身
# 函数的递归不应该是无限循环过程,真正的递归函数应该满足两个要求
1、每次递归,复杂度必须降低(下一次递归要比上一次递归解答)
2、必须要有明确的结束条件
1 、直接调用自己
def index():
print('from index')
index()
index()
"""
RecursionError: maximum recursion depth exceeded while calling a Python object # 报错
python解释器自带应急机制,受到最大递归深度超出限制
"""
2 、间接调用自己
def index():
print('from index') # 3 # 7
func() # 4 # 8
def func():
print('from func') # 1 # 5
index() # 2 # 6
func()
""" maximum recursion depth exceeded while calling a Python object """
# python最大递归深度——997、998、1000都可以,官方为1000
3 、递归函数练习
1、一共五排学生,第一个学生说他比他后面的大两岁,依次到第五排,第五排说我18,求第一个多大
def get_age(a):
if a == 1: # 到最后一排时,为18
return 18
return get_age(n-1)+2 # 每往前一排,增加两岁
print(get_age(5)) # 26
2、l1 = [1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]
循环打印每个列表的第一个数字
判断是不是数字,是打印
def get_num(l):
for i in l: # 当列表为空时,不再打印
if isinstance(i,int): # 判断i是不是整数
print(i)
else:
get_num(i)
get_num(l1)
# 1 2 3 4 5 6 7 8 9
五、算法之二分法
算法含义:就是解决问题的有效方法
算法之二分法:是算法里面最入门的,主要是感受
"""二分法使用前提:数据集必须有先后顺序(升序、降序)"""
算法二分法练习
l1 = [13,21,35,46,52,67,76,87,99,123,213,321,432,564,612]
# 通过二分法,将76挑出来
def get_target(l1,target_num):
if len(l1) == 0:
print('不好意思 真的没有 找不到')
return
# 1.获取中间元素的索引值(只能是整数,使用//)
middle_index = len(l1) // 2
# 2.判断中间索引对应的数据与目标数据的大小
if target_num > l1[middle_index]:
# 3.如果中间的元素大于目标数据 那么保留数据集的左边一半
l1_left = l1[middle_index+1:]
print(l1_left)
# 3.1 对左侧继续二等分
get_target(l1_left,target_num)
# 4.如果中间的元素小于目标数据 那么保留数据集的右边一半
elif target_num < l1[middle_index]:
l1_right = l1[:middle_index]
print(l1_right)
# 4.1.对右侧继续二分
get_target(l1_right,target_num)
else:
print('找到了',target_num)
get_target(l1,76)
#
[13, 21, 35, 46, 52, 67, 76]
[52, 67, 76]
[76]
找到了 76
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)