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']
原文地址:https://www.cnblogs.com/huluhuluwa/p/13174123.html