多层、有参装饰器、递归函数和算法之二分法

今日内容总结

一、给多个函数加上用户认证(代码)

二、多层装饰器

三、有参装饰器

四、递归函数

五、算法之二分法

一、给多个函数加上用户验证

要求:给多个函数加上用户认证功能
    通过名和密码:'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解释器自带应急机制,受到最大递归深度超出限制
"""

qnvw4S.jpg

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 

qup6RU.jpg

posted @   未月  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示