装饰器补充和算法
![]()
多层装饰器
"""
语法糖会将紧挨着被装饰对象的名字当做参数自动传入装饰器函数中
"""
eg:
# 判断七句print执行顺序
def outter1(func1):
print('加载了outter1')
def wrapper1(*args, **kwargs):
print('执行了wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def outter2(func2):
print('加载了outter2')
def wrapper2(*args, **kwargs):
print('执行了wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def outter3(func3):
print('加载了outter3')
def wrapper3(*args, **kwargs):
print('执行了wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3
@outter1
@outter2
@outter3
def index():
print('from index')
index()
运行结果:
加载了outter3
加载了outter2
加载了outter1
执行了wrapper1
执行了wrapper2
执行了wrapper3
from index
分析:
'''
当我们使用语法糖时,语法糖会将紧挨着的被装饰对象传入装饰器函数,所以,会先从outer3加载到outter1。然后执行index(),内部放wrapper函数才被调用,由于最后加载的outter1,所以当调用阶段开始时,index = outter1(index),所以执行内部函数从wrapper1开始
'''
有参装饰器
装饰器本质就是一个两层嵌套的闭包函数,其中外层函数的参数用来传递被修饰对象,内层函数用来传递被修饰对象的参数,两者都不可以变,变了就不满足装饰器的条件了,所以,当我们需要传其他参数时,就必须要使用有参装饰器,其本质就是装饰器再次被闭包
eg:
# 不同的数据存放
def data_type(data_type):
def database(func_name):
def inner(*arge, **kwargs):
if data_type == 1:
print('存入数据库1')
elif data_type == 2:
print('存入数据库2')
func_name()
return inner
return database
@data_type(1) # 语法糖加括号,会有限执行函数,然后返回值执行语法糖,此处data_type(1)先执行,然后返回database,再执行语法糖@database
def index():
print('操作成功')
index()
运行结果:
存入数据库1
操作成功
"""
函数名加括号 执行优先级最高
装饰器最多就三层嵌套,想传多个参数直接在最外层一次性传入
"""
![]()
递归函数
# 本质:递归函数也称为函数的递归
函数在运行过程中直接或者间接调用了自身
# 最大递归深度:
就是可以最大循环调用自身的次数,python官方说明,最大递归深度是1000,实际项目可能是997,998
# 查看和修改最大递归深度
eg:
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)
print(sys.getrecursionlimit())
运行结果:
1000
2000
"""
函数的递归不应该是无限循环的过程 真正的递归函数应该要满足两个要求
1.每次递归 复杂度必须降低(下一次递归要比上一次递归解答)
大白话 越往下递归应该离解决问题的答案越近
2.必须要有明确的结束条件
"""
# 求年龄:前排比后排大两岁,一共有五排,最后一人18岁,问第一排几岁?
eg:
def age(n):
if n == 1:
return 18 # 明确的结束条件
else:
return age(n - 1) + 2 # 调用自身函数
print(age(5))
运行结果:
26
递归练习
l1 = [1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]
'''需求:循环打印出列表中每一个数字'''
eg:
def num_list(l):
for i in l:
if isinstance(i,int): # 如果是整形则输出
print(i)
else:
num_list(i) # 不是整形执行递归
num_list(l1)
算法
# 什么是算法?
算法就是解决问题的有效方法
"""
算法比较偏向于学术研究 很枯燥 并且产出很少
甚至只有非常大的互联网公司才会有算法部分
算法工程师薪资待遇很高 但是产出很少
有时候甚至几年都没有任何的成果 有点类似于研究所!!!
"""
# 所以,算法研究跟我们基本没毛关系,我们用人家写好的就行了
# 二分法
用处:找数的
要求:数据集必须有序的
l1 = [13,21,35,46,52,67,76,87,99,123,213,321,432,564,612]
# 查找一个数 123
eg:
def get_num(l,num):
if len(l) == 0:
print('真的没有')
return
# 砍两半
count = len(l) // 2
if num == l[count]:
print('找到了')
return
elif num > l[count]:
get_num(l[count+1:],num)
else:
get_num(l[:count],num)
get_num(l1, 123)
运行结果:
找到了
![]()