函数-4

函数-4

目录
装饰器

  • 多层装饰器

  • 有参装饰器

递归函数

算法

  • 二分法

装饰器

  • 多层装饰器
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    # index = outter1(wrapper2)
@outter2    # wrapper2 = outter2(wrapper3)
@outter3    # wrapper3 = outter3(index函数名)
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 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 =='jason':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()
"""
我们以后遇到的最复杂的装饰器就是上面的 不会比上面更复杂 
目的仅仅是为了给装饰器代码传递更多额外的数据
"""

递归函数

  • 递归函数的概念
    函数直接或间接调用了函数本身就被称为是递归函数

  • 直接调用递归函数

 def index():
     print('from index')
     index()
 index()
  • 间接调用递归函数
 def index():
     print('from index')
     func()
 def func():
     print('from func')
     index()
 func()

python中允许函数最大递归调用的次数
官方给出的限制是1000 用代码去验证可能会有些许偏差(997 998...)

  • 递归函数所应用的场景
    递推:一层层往下寻找答案
    回溯:根据已知条件推导最终结果
    递归函数
    1.每次调用的时候都必须要比上一次简单!!!
    2.并且递归函数最终都必须要有一个明确的结束条件!!!
l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
# 循环打印出列表中所有的数字
# 1.for循环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, 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:
        # 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(l1, 1000)

二分法缺陷
1.数据集必须是有序的
2.查找的数如果在开头或者结尾 那么二分法效率更低!!!

作业

  • 1.尝试编写有参函数将多种用户验证方式整合到其中
    直接获取用户数据比对
    数据来源于列表
    数据来源于文件
info = [['jcs', '123'], ['jason', '123']]


def outer(condition):
    def login(func):
        def inner(*args, **kwargs):
            username = input('请输入用户名:').strip()
            password = input('请输入密码:').strip()

            if condition == '列表':
                print('使用列表作为数据来源')
                for i in info:

                    if username == i[0] and password == i[1]:
                        res = func(*args, **kwargs)
                        return res

                else:
                    print('用户名或密码错误')

            elif condition == '文件':
                print('使用文件作为数据来源')
                with open(r'user.txt', 'r', encoding='utf8') as f:
                    for i in f:
                        i = i.strip().split(',')
                        if username == i[0] and password == i[1]:
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('权限不够,无法执行')

            else:
                print('没有这个方式')

        return inner

    return login


@outer('列表')
def register():
    print("登录成功")


@outer('文件')
def register():
    print('登陆成功')

register()
  • 2.尝试编写递归函数
    推导指定某个人的正确年龄
    eg: A B C D E 已知E是18 求A是多少
def func(n):   # 定义一个函数名为func,参数为n 的函数
    if n == 1:     # 如果参数为1 ,返回n的值
        return 18   # 将18赋值给n
    else:
        return  2 + func(n-1)   # n不等于1, 返回依此加2


A = func(5)  # 执行5次
print(A)
posted @ 2022-07-06 20:02  Nirvana*  阅读(37)  评论(0)    收藏  举报