Python多层装饰器与递归函数

1.多层装饰器

Python的装饰器原理能够在不破坏函数原本结构的基础上,加入新的功能创新。当我们需要对一个函数补充不同的功能,可能需要用到多层的装饰器,接下来给大家演示一个多层装饰器的解题思路。


				'''注意语法糖会将下面紧挨着的函数当作参数传递给@符号后面的函数名运行'''
			
		def outter1(func1):						12.这个时候func1就接到了wrapper2的函数名了
		    print('加载了outter1')				13.打印加载outter1
		    def wrapper1(*args, **kwargs):		14.在创建新的wapper1 return
		        print('执行了wrapper1')			16.打印wrapper1
		        res1 = func1(*args, **kwargs)	17.遇到括号优先执行 这个时候的fun1是wrapper2所以直接跳到wrapper2
		        return res1
		    return wrapper1						15. 返回 wrapper1
		
		def outter2(func2):						07.所以这个时候的func2就是wrapper3
		    print('加载了outter2')				08.打印加载outter2 
		    def wrapper2(*args, **kwargs):		09.然后定义了wrapper2 下一步return
		        print('执行了wrapper2')			18.打印wrapper2 
		        res2 = func2(*args, **kwargs)	19.func2就是wrapper1
		        return res2
		    return wrapper2						10.这个时候返回wrapper2就是index返回了
		
		def outter3(func3):						02.这个时候fun3是真的index 运行fun3函数
		    print('加载了outter3')				03.打印加载了outter3 函数定义不用看代码函数体代码 所以下一步 return
		    def wrapper3(*args, **kwargs):	
		        print('执行了wrapper3')			20.打印wrapper3
		        res3 = func3(*args, **kwargs)	21.func3就是index跳到index
		        return res3
		    return wrapper3						04.所以这时候index的返回值就是wrapper3 这个时候wrapper就成了函数名 再次触发 outter2
		
		
		@outter1			11.这个时候index就到了outter1在运行outter1		15.这个时候就变成伪装的 index = routter1(wrapper2)
		@outter2			06.所以这个时候wrapper3会传到outter2里面在运行
		@outter3			01.这个时候就会把真正的index传给outter3 所以 outer3(index) 括号优先级执行	05.所以这个时候就是 wrapper3 = outter3(index)
		def index():
		    print('from index')					22.结束
		index()

2.有参装饰器

现在我们有一个已经设置好了的用户登录校验的函数,但是我们想知道这个用户的数据来源来自哪里?已知有了列表、字典、文件所以我们该用什么来实现呢?就需要用到有参装饰器啦!

		'''这是已知的用户登陆函数'''
		
		def login_auth(func_name):
		    def inner(*args, **kwargs):
		        username = input('username>>>:').strip()
		        password = input('password>>>:').strip()
		        if username == 'meijin' 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 =='meijin':
		            	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()

3.递归函数

		递归函数的概念
			函数直接接调用了自己或者是间接使用了自己就是递归调用
		ex:
				def index():							在全局寻找index 无限循环
					print('from index')					上面说法其实也是错误的
					index()								不会无限循环 python的循环次数是有限的
												 
				index()									官方给出的限制是1000 用代码去验证可能会有些许偏差(997 998...)
	那我们就在测试测试:
		count = 1										计数器默认=1
		def index():									创建一个函数index
		    print('from index')							打印from index
		    global count								global 修改全局空间中的变量名
		    count += 1  # count = count + 1				运行一次+1
		    print(count)								
		    index()										调用index 进入循环
		index()							

	小技巧:
		import sys										倒入系统板块
		print(sys.getrecursionlimit())  				内置方法. 1000是递归最大次数
		sys.setrecursionlimit(2000)  					可以自定义最大次数
		print(sys.getrecursionlimit())					

在这里插入图片描述

	递归函数真正的应用场景   
		递推:一次次寻找答案直到找到答案   
		回溯:根据最终答案在向回推导找到答案
	递归函数 
		1.每次调用的时候都必须感觉要比上一次简单!!!    
		2.并且递归函数最终都必须要有一个明确的结束条件!!!
	ex:	我们已知有一个列表,但是呢我只要里面的数字不要中括号这么获取呢!
		就可以用到我们学习的递归函数了
		
		l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
		def get_num(l1):					
		    for i in l1:						循环打印出列表中所有的数据值	
		        if isinstance(i,int):			判断当前对象数据值是否是数字 
		            print(i)					如果是则打印
		        else:
		            get_num(i)					如果不是则继续循环打印列表剩余列表
		get_num(l1)
	

4.算法之二分法

	什么是算法?
		算法不是我们想的什么加减乘除上面的算法,而是指能解决问题的方法就是算法
		算法永远都在精进 但是很少有最完美的算法
		二分法是所有算法里面最简单的算法但是也有人说二分法不是算法
	跟二分法类似的还有?
		二分法、快拍、插入、堆排、链表、双向链表、约瑟夫问题
	比如我们想从下方列表中获取到999的这个数据值 我们用二分法来试试	
ex:	
	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								
	        
	    middle_index = len(l1) // 2  					获取整个列表中间的值
	    middle_value = l1[middle_index]					
	    
	    if target_num > middle_value:  					判断目标数据值在不在右边的数据值列表里面
	        right_l1 = l1[middle_index + 1:]  			如果数据值在列表的右边再加一位数据继续
	        print(right_l1)								打印右边截取的列表
	        get_num(right_l1, target_num)				返回到最开始再次比值看是否在右边继续截取
	        
	    elif target_num < middle_value:					判断目标数据值在不在左边的数据值列表里面
	        left_l1 = l1[:middle_index]					用left_l1来接手左边的数据列表
	        print(left_l1)								打印左边截取的列表
	        get_num(left_l1, target_num)				返回到最开始再次比值看是否在左边继续比较截取
	        
	    else:
	        print('找到了', target_num)				
	        
 	get_num(l1, 999)

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoisMay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值