zoukankan      html  css  js  c++  java
  • 015.Python之装饰器叠加、函数递归及匿名函数

    一、同时叠加多个装饰器

    (一)同时叠加多个装饰器:加载顺序与执行顺序

    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()
    

    二、函数的递归调用:

    (一)什么是函数递归调用

    函数的递归调用指的是,在调用一个函数的过程中又直接或者间接地调用了自己。

    递归调用就是一个循环的过程,循环的次数取决何时结束调用自身

    # 函数的递归调用就是一个循环的过程
    def f1():
        print('ffffff')
        f1()
    
    f1()  #  无限循环调用,直到内存溢出报错结束
    
    
    def f1():
        print('from f1')
        f2()
    
    def f2():
        print('from f2')
        f1()
    
    f1()  #  无限循环调用,直到内存溢出报错结束
    

    (二)递归调用的两个阶段:

    必须在满足某种条件下结束递归调用,然后向上一层一层返回

    递归调用经历两个阶段:

    1.回溯:

    向下一层一层地调用

    2.递推:

    在某一层终止调用,开始向上一层一层返回

    """
    salary(5) = salary(4) + 1000
    salary(4) = salary(3) + 1000
    salary(3) = salary(2) + 1000
    salary(2) = salary(1) + 1000
    salary(1) = 3000
    
    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)  # 8000
    
    # 总结:
    # 递归调用就是一个循环的过程,循环的次数取决何时结束调用自身
    

    (三)递归的应用

    # 应用1
    list1 = [1, [2, [3, [4, [5, [6, [7, [9, ]]]]]]]]
    
    def func(nums_l):
        for x in nums_l:
            if type(x) is list:
                func(x)
            else:
                print(x)
    
    
    func(list1)  1 2 3 4 5 6 7 8 9
    
    # 应用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)
    

    三、匿名函数

    (一)匿名函数是什么

    匿名函数就是没有名字的函数。

    (二)应用场景:

    只用于临时使用一次的场景。

    def f(x,y):
        return x+y
    
    f = (lambda x, y: x + y)  # 上述函数可以简写为匿名函数的形式
    print(f)  # <function <lambda> at 0x000001CB97139040>
    res = f(1, 2)
    print(res)  # 3
    
    res=(lambda x, y: x + y)(1,2)  # 匿名函数的调用
    print(res)  # 3
    
    # 匿名函数通常用于与其他函数配合使用
    salaries = {
        "zegon": 3600,
        "lxx": 3000,
        "axx": 4000
    }
    
    # 取薪资最高的那个人的人名
    print(max([22,333,44,555]))   # 555
    
    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']
    
  • 相关阅读:
    微软并行编程类库Parallel Extensions初探 Part1 (转)
    一些很酷的.Net技巧(上)
    【Silverlight】Silvelright端获取托管web项目中xap的路劲
    【Silverlight】Silvelright获取web端的xml
    博客开始第一天
    asp.net过滤HTML方法
    程序员应该懂的道理
    生成缩略图
    转:用自定义IHttpModule实现URL重写
    android 之helloword
  • 原文地址:https://www.cnblogs.com/huluhuluwa/p/13174123.html
Copyright © 2011-2022 走看看