目录
一、同时叠加多个装饰器
(一)同时叠加多个装饰器:加载顺序与执行顺序
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']