python学习Day18

Day 18

今日内容概要

  • 多层装饰器
  • 有参装饰器
  • 递归函数
  • 算法(二分法)
  • 函数相关偷懒操作

今日内容详细

1.多层装饰器
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 # index=outter1(wrapper2)   index现在就是wrapper1
@outter2 # wrapper2=outter2(wrapper3)
@outter3 # wrapper3=outter3(真正的index函数名)
def index():
    print('from index')
1.一个函数上面加了三个语法糖装饰器,是怎么执行的?
   加载了123 执行了321 from index
2.执行后上面7print先后打印顺序是什么?
'''
语法糖的功能:
	会自动将下面紧挨着的函数名当作参数传递给@符号后面的函数名(加括号调用)
涉及到多个语法糖装饰一个函数名:
	语法糖从下往上执行 只有最后一个会重命名操作
'''
2.有参装饰器
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):#把需要的额外数据放在这里
    def login_auth(func_name): #这个地方不能放condition 只能接收被装饰的函数名 不能再填写其他形参
        def inner(*args, **kwargs): #这个地方也不能放condition 加了会改变原函数的调用方式
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            #根据用户需求执行不同代码
            if type == '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()
#这样做的目的仅仅是为了给装饰器代码传递更多额外的数据
3.递归函数
'''
递归函数:
	函数直接或间接调用了自己就叫递归调用
'''
1.递归直接调用:(自己调自己)
def index():#1.定义一个函数index()
    print('from index')#3.执行函数体内部代码
    index()#4.直接调用index()  此时的顺序就是123434343434一直重复 这就是函数递归调用
index()#2.调用index()函数

2.递归间接调用:(我调别人别人调我)
def index():#1.把函数名称放在全局空间中
    print('from index')#6.#10.
    func()#7.#11
def func():#2.把函数名称放在全局空间中
    print('from func')#4.#8.
    index()#5.#9.
func()#3.调用函数func()  456789就会一直重复
——————————————————————————————————————————————————————————————————
'python中官方允许函数中最大调用的次数限制是1000 但是用代码验证可能会是996、997..'
1)计数器验证递归最大次数:
count = 1
def index():
    print('from index')#
    global count #局部名称空间改全局需要加global关键字
    print(count)
    count +=1
    index()
index()#996次

2)模块获取官方递归最大次数
import sys
print(sys.getrecursionlimit())#1000

#模块修改递归次数
import sys
sys.setrecursionlimit(2000)#把递归次数定义为2000
print(sys.getrecursionlimit())
递归函数的应用场景:
	递推:一层一层往下寻找答案
	回溯:根据已知条件得出最终结果
    
写递归函数需注意:
	1.每次调用的时候都必须'比上一次简单'
    2.递归函数最终都必须要有一个明确的'结束条件'
    例如:问A名字,A说我比B大两岁,B说我比C大1岁,C说我18岁。
         这个过程就是调用的过程,C就是明确的结束条件
递归函数练习:
l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
# 循环打印出列表中所有的数字
# 1.for循环l1里面所有的数据值
# 2.判断当前数据值是否是数字 如果是则打印
# 3.如果不是则继续for循环里面所有数据值
# 4.判断当前数据值是否是数字 如果是则打印
# 5.如果不是则继续for循环里面所有数据值
# 6.判断当前数据值是否是数字 如果是则打印

错误示范:
l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
for i in l1:
    if isinstance(i,int):#判断某个数据类型是不是属于另外数据类型 判断i是否属于整型
        print(i)#如果是则打印i
    else:
        for j in i:#如果不是整型则继续让j去循环取值
            if isinstance(j,int):
                print(j)
'这样做会一直重复上述操作 如果有1000个数据值则要重复1000次 所以我们要用递归函数'
————————————————————————————————————————————————————————————————————————————
正确示范:
l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]#1.
def num(l1):#2.
    for i in l1:#4.让i循环打印l1
        # print(i)#1和[2, [3, [4, [5, [6, [7, [8, [9, [10]]]]]]]]]
        if isinstance(i, int):#判断某个数据类型是不是属于另外数据类型 判断i是否属于整型
            print(i)#如果是则打印i
        else:
            num(i)#如果不是整型则把后面的列表传给函数继续重复第4步
num(l1)#3.
4.算法(二分法)
1.什么是算法?
	算法就是解决问题的方法(比如物品坏了,我有几种方法去解决)
'''
算法永远都在精进,很少有最完美的算法
小公司一般没有算法工程师,只有大厂才有,薪资也很高
很多面试官都喜欢问算法相关问题
算法分为:二分法、快拍、插入、堆排、链表、双向链表、约瑟夫问题
'''
算法——二分法:
	算法中最简单的算法,就是把数据拆成两半去判断,然后再拆成两半去判断,直到找到需要的数据,类似于递归函数
    
eg:用算法判断999在不在以下列表中,如果在就取出该值
l1 = [11, 23, 32, 45, 65, 78, 90, 123, 432, 467, 567, 687, 765, 876, 999, 1131, 1232]
————————————————————————————————————————————————————————————————————————————————
方法一:用for循环
缺陷:如果列表中数据特别多 需要的数据在最后几个 那代码执行的时间就会做多余的浪费
————————————————————————————————————————————————————————————————————————————————
方法二:二分法来做
缺陷:1.数据必须是有顺序的,不能打乱顺序
      2.查找的数字如果在开头或者结尾,效率可能会很低
l1 = [11, 23, 32, 45, 65, 78, 90, 123, 432, 467, 567, 687, 765, 876, 999, 1131, 1232]
#5.根据第三第四步判断需要用递归函数来操纵
def num(l1,number):#l1一会要当作参数传进来 number也当作参数放进去用于以后用户随意修改要查的数据
    #8.添加递归函数的结束条件
    if len(l1)==0:
        print('找不到')
        return
    #1.先获取数据列表中中间的数
    middle=len(l1)//2#统计出列表中有多少数据再整除得到中间数的索引值
    value=l1[middle]#把列表中中间的值赋值给value
    #2.判断中间的数据值与目标数据值谁大谁小
    if number > value:
        #3.说明查找的数据在列表大的那一边
        right_l1 = l1[middle+1:]#利用列表的切片取值取当前位置一直到后面所有,因为当前位置肯定比999小所以让索引加1
        #3.1获取右边中间的值
        #3.2与目标数据值对比
        #3.3根据大小切割数据集
        #6.添加递归函数代码
        print(right_l1)
        num(right_l1,number)#把右边的列表当作新列表传给参数,再把要对比的数据传给参数
    elif number < value:
        #4.说明查找的数据在列表小的那一边
        left_l1 = l1[0:middle]#利用列表索引取值取从0开始一直到当前位置前(顾头不顾尾)所有值
        # 4.1获取左边中间的值
        # 4.2与目标数据值对比
        # 4.3根据大小切割数据集
        #7.添加递归函数代码
        print(left_l1)
        num(left_l1,number)
    else:
        print('该位置就是目标数据所在位置',number)

num(l1,999)

作业:

1.尝试编写有参函数将多种用户验证方式整合到其中
	直接获取用户数据比对
 	数据来源于列表
 	数据来源于文件
2.尝试编写递归函数
	推导指定某个人的正确年龄
    	eg: A B C D E  已知E是18 求A是多少
posted @   逢诱  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示