zoukankan      html  css  js  c++  java
  • 函数(五)——装饰器,递归调用,匿名函数

    今日内容概要:

    一、巩固复习

    二、同时叠加多个装饰器(重点)

    三、函数的递归调用(重点)

    四、匿名函数(重点)

    内容详解:

    一、巩固复习

    1、一定要牢记的装饰器模板

    def outter(func):
        def wrapper(*args,**kwargs):
            # 可放新增的功能
            res=func(*args,**kwargs)
            # 可放新增的功能
            return res
        return wrapper

    2、语法糖

    3、wraps

    二、同时叠加多个装饰器

    同时叠加多个装饰器:加载顺序与执行顺序
    def deco1(func1):  # func1 = wrapper2
        def wrapper1(*args, **kwargs):
            print('=======>wrapper1')
            res1 = func1(*args, **kwargs)  #wrapper2==》未完
            return res1
        return wrapper1
    
    def deco2(func2):  # func2 = wrapper3
        def wrapper2(*args, **kwargs):
            print('=======>wrapper2')
            res2 = func2(*args, **kwargs)  # wrapper3==》未完
            return res2
        return wrapper2
    
    def deco3(func3):  # func3 = index
        def wrapper3(*args, **kwargs):
            print('=======>wrapper3')
            res3 = func3(*args, **kwargs)  # index==》未完
            return res3
        return wrapper3
    
                 # index = wrapper1
    @deco1  # deco1(wrapper2)=>wrapper1
    @deco2  # deco2(wrapper3)=>wrapper2
    @deco3  # deco3(index)=>wrapper3
    def index():
        print("from index")
        return 123
    
    
    res=index()  # res=wrapper1()
    #原理分析:
    # =======>wrapper1
    # =======>wrapper2
    # =======>wrapper3
    # from index

    结论:

    1、装饰器的加载顺序是自下而上的
    2、装饰器的执行顺序是自上而下的
    import time
    
    
    def timmer(func):
        def wrapper1(*args, **kwargs):
            print('===>wrapper1')
            start = time.time()
            res = func(*args, **kwargs)
            stop = time.time()
            print(stop - start)
            return res
    
        return wrapper1
    
    
    def auth(func):
        def wrapper2(*args, **kwargs):
            print('===>wrapper2')
            name = input("请输入您的账号:").strip()
            pwd = input("请输入您的账号:").strip()
            if name == "egon" and pwd == "123":
                print('登录成功')
                res = func(*args, **kwargs)
                return res
            else:
                print("账号密码错误")
    
        return wrapper2
    
    
    @auth
    @timmer
    def index():
        time.sleep(1)
        print("from index")
        return 123
    
    
    # wrapper2=>wrapper1=>index
    
    index()  # wrapper1()
    #示范

    三、函数的递归调用

    函数的递归调用:指的是在调用一个函数的过程中又直接或者间接地调用了自己
    函数的递归调用就是一个循环的过程
    #1
    def f1():
        print('ffffff')
        f1()
    
    f1()
    
    #2
    def f1():
        print('from f1')
        f2()
    
    def f2():
        print('from f2')
        f1()
    
    f1()
    递归调用应该遵循的一个大前提是:必须在满足某种条件下结束递归调用,然后向上一层一层返回
    递归调用经历两个阶段
    1、回溯:向下一层一层地调用
    2、递推:在某一层终止调用,开始向上一层一层返回

    #通过几个人的薪资最终计算出刚开始问的人的薪资
    #分析
    salary(4) = salary(3) + 1000
    salary(3) = salary(2) + 1000
    salary(2) = salary(1) + 1000
    salary(1) = 5000
    
    salary(n) = salary(n-1) + 1000 # n > 1
    salary(1) = 3000               # n = 1
    #解答
    def salary(n):  # n = 1
        if n == 1:
            return 5000
        return salary(n - 1) + 1000
    
    res = salary(4)
    print(res)
    #示范——关于薪资计算
    总结:
    递归调用就是一个循环的过程,循环的次数取决何时结束调用自身
    #将列表中元素全部取出
    l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]]
    def func(num_1):
        for x in num_1:
            if type(x) is list:
                func(x)
            else:
                print(x)
    func(l)
     
    # 应用2:二分法
    # 有一个有序排列的数字列表,判断数字是否存在于此列表
    nums = [-3, 1, 5, 7, 11, 13, 21, 37, 45]
    
    # 方案一:效率低
    find_num = 45
    for num in nums:
        if find_num == num:
            print('找到啦')
            break
    else:
        print("不存在")
    
    # 方案二:二分法
    nums = [-3, 1, 5, 7, 11, 13, 21, 37, 45]
    
    find_num = 47
    
    def search(find_num,nums):
        print(nums)
        if len(nums) == 0:
            print('不存在')
            return
        mid_index = len(nums) // 2
        if find_num > nums[mid_index]:
            # 查找范围:右半部分
            new_nums = nums[mid_index + 1:]
            search(find_num,new_nums)
        elif find_num < nums[mid_index]:
            # 查找范围:左半部分
            new_nums = nums[:mid_index]
            search(find_num,new_nums)
        else:
            print("找到啦")
    
    search(find_num,nums)

    四、匿名函数

    匿名函数:就是没有名字的函数  
    匿名函数只用于临时使用一次的场景
    匿名函数英文名:lambda
    定义函数:
    #def用于定义有名函数
    def f(x,y): return x+y
    #lamabda用于定义无名函数
    lambda 参数:返回值
    print
    (lambda x, y: x + y)
    调用匿名函数:
    #lambda不规范使用,平时都不会这么用
    #方式一、
    f = (lambda x, y: x + y) res = f(1, 2) print(res) #方式二、 res=(lambda x, y: x + y)(1,2) print(res)
    匿名函数通常用于与其他函数配合使用
    #匿名函数应用:
    salaries = { "zegon": 3600, "lxx": 3000, "axx": 4000 } # 取薪资最高的那个人的人名 print(max([22,333,44,555])) #
    max 运行原理:传入可迭代带对象,将其转换成迭代器对象(跟for list运行原理一样)
    def func(k): 
      
    return salaries[k]
    print(max(salaries,key=func))# axx

    print(max(salaries,key=lambda k:salaries[k])) # axx
    print(min(salaries,key=lambda k:salaries[k]))# lxx
    print(sorted(salaries,key=lambda k:salaries[k],reverse=True)) # ['axx', 'zegon', 'lxx']
  • 相关阅读:
    python3中的线程简记
    python3中的SMTP简记
    sql依赖注入简记
    python Internet模块
    python-socket编程简例
    1.docker简介及安装
    kvm迁移
    kvm网络管理
    kvm存储池和存储卷
    2.标准数据类型--字符串
  • 原文地址:https://www.cnblogs.com/guojieying/p/13166669.html
Copyright © 2011-2022 走看看