装饰器重要补充,递归函数以及简单算法(二分)

多层装饰器

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

def outter2(func2):  # func2 = wrapper3
    print('加载了outter2')
    def wrapper2(*args, **kwargs):
        print('执行了wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2

def outter3(func3):  # func3=index
    print('加载了outter3')
    def wrapper3(*args, **kwargs):
        print('执行了wrapper3')
        res3 = func3(*args, **kwargs)
        return res3
    return wrapper3


@outter1  # wrapper1=outter1(wrapper2)
@outter2  # wrapper2=outter2(wrapper3)
@outter3  # wrapper3=outter3(index)
def index():
    print('from index')

index()
"""
加载了outter3
加载了outter2
加载了outter1
执行了wrapper1
执行了wrapper2
执行了wrapper3
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 inner()
"""
需求:在装饰器内部可以切换多种数据来源
    列表
    字典
    文件
"""
def outer(condition,root):
    def login_auth(func_name):
        def inner(*args,**kwargs):
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            if root == 'jason':
                print('超级管理员')
            if condition == '列表':
                print('使用列表为数据来源,比对用户数据')
            elif condition == '字典':
                print('使用字典为数据来源,比对用户数据')
            elif condition == '文件':
                print('使用文件作为数据来源,比对用户数据')
            else:
                print('去你妹的  我只有上面几种方式')
        return inner
    return login_auth
@outer('文件','jason')
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 = 0
# def index():
#     print('from index')
#     global count
#     count +=1
#     print(count)
#     index()
# index()
# import sys
# print(sys.getrecursionlimit())  # 1000
# sys.setrecursionlimit(2000)
# print(sys.getrecursionlimit())  # 2000

"""
递归函数真正的应用场景
    递推:一层层往下寻找答案
    回溯:根据已知条件推到最终结果
递归函数:
    1.每次调用的时候都必须要比上一次简单
    2.并且递归函数最终都必须要有一个明确的结束条件
"""
l1 = [1, [2, [3, [33, [5, [6, [100, [8, [9, [10, ]]]]]]]]]]
# 循环打印出列表中所有的数字
def get_num(a):
    for i in a:
        if isinstance(i,int):
            print(i)
        else:
            get_num(i)
get_num(l1)

算法之二分法

什么是算法
    算法就是解决问题的方法
算法永远都在精进  但是很少有最完美的算法
    算法很多时候可能没什么用
    常见面试算法如下:
	'二分法'     '快排'     '插入'     '堆排'     '链表'    '双向链表'     '约瑟夫问题'
'二分查找代码实现'
def get_num(l,target):
    mid_index = (0+len(l)-1)//2
    if l[mid_index] == target:
        return True
    elif target>l[mid_index]:
        return get_num(l[mid_index+1:],target)
    else:
        return get_num(l[:mid_index],target)

l1 =[1,2,3,6,9,13,67,98,222,777,989,1345,2655,7899]
print(get_num(l1, 2))
"""
二分法缺陷
   1.数据集必须是有序的
   2.查找的数如果在开头或者结尾,效率更低
"""

案例

尝试编写递归函数
	推导指定某个人的正确年龄
    	eg: A B C D E  已知E是18 求A是多少
	
	def get_age(n):
    if n==1:
        return 18
    else:
        return get_age(n-1)+2


print(get_age(5))  # 26
posted @ 2022-07-06 19:35  荀飞  阅读(16)  评论(0编辑  收藏  举报