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.算法二分法,注意的点是,内容必须是排序好的;比较麻烦的是寻找的值在开头或者结尾
posted @ 2022-07-06 22:07  名字长的像一只老山羊  阅读(72)  评论(0编辑  收藏  举报