函数知识(多层装饰器、有参装饰器、递归函数、二分法)

多层装饰器

def outter1(func1):
    print('加载了outter1')
    def wrappper1(*args,**kwargs):
        print('执行了wrapper1')
    res1 = func1(*args, **kwargs)
    return res1

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 = func(*args,**kwargs)
        return res3
    return wrapper3

@outter1
@outter2
@outter3
def index():
    print('from index')

有参装饰器

def login_auth(func_name):
    def innner(*args,**kwargs):
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        if username == 'curry' and password == '123':
            res = func_name(*args,**kwargs)
            return res
        else:
            print('用户权限不够 无法调用函数')
    return innner
'''
需求:在装饰器内部可以切换多种数据来源
    列表
    字典
    文件
'''
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 =='curry':print('vip')
            if condition == '列表'print('使用列表作为数据来源 比对用户数据')
            elif condition == '字典'print('使用字典作为数据来源 比对用户数据')
            elif condition == '文件'print('使用文件作为数据来源 比对用户数据')
            elseprint('抱歉 我目前只有上面几种方式')
        return inner
    return login_auth
@outer('文件''curry')
def index():
    print('from index')
index()
"""
目的是为了给装饰器代码传递更多额外的数据
"""

递归函数

概念
	函数直接或者间接调用了自己>>>:递归调用
        递归调用:直接调用
def index():
    print('from index')
    index()
index()
递归调用:间接调用
def index():
    print('from index')
    func()
def func():
    print('from func')
    index()
func()
"""
python中允许函数最大递归调用的次数
    官方给出的限制是1000 用代码去验证可能会有些许偏差(997 998...)
"""

count = 1
def index():
    print('from index')
    global count
    count += 1  # count = count + 1
    print(count)
    index()
index()
import sys
print(sys.getrecursionlimit())  # 1000  获取递归最大次数
sys.setrecursionlimit(2000)  # 自定义最大次数
print(sys.getrecursionlimit())
"""
递归函数真正的应用场景
    递推:一层层往下寻找答案
    回溯:根据已知条件推导最终结果
递归函数
    1、每次调用的时候都必须要比上一次简单!!!
    2、并且递归函数最终都必须要有一个明确的结束条件!!!
"""
l1 = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,]]]]]]]]]]
循环打印出列表中所有的数字
1for循环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,22,33,44,65,78,92,123,456,488,567,678,765,876,999,1122,1234]
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(11,1000)
"""
二分法缺陷
    1、数据集必须是有序的
    2、查找的数如果在开头或者结尾,那么二分效率更低
"""   
posted @   初学者-11  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示