多层装饰器
def outter1(func1): # 1.定义函数outter1设置参数func1
# 18.func1其实就是warpper2
print('输出outter1') # 19.打印 输出哦outter1
def wrapper1(*args, **kwargs): # 20.定义warpper1
print('输出wrapper1') # 24
res1 = func1(*args, **kwargs) # 25 func1是warpper2,调用函数warpper2
return res1 # 34
return wrapper1 # 21.返回warpper1
def outter2(func2): # 2.定义函数outter2设置参数func2
# 11.func2其实就是warpper3
print('输出outter2') # 12.打印 输出outter2
def wrapper2(*args, **kwargs): # 13.定义warpper2
print('输出wrapper2') # 26
res2 = func2(*args, **kwargs) # 27 调用函数warpper3
return res2 # 33
return wrapper2 # 15.返回wrapper2
def outter3(func3): # 3.定义函数outter3设置参数func3
# 5.func3其实就是真正的index
print('输出outter3') # 6.打印 输出outter3
def wrapper3(*args, **kwargs): # 7.定义warpper3
print('输出wrapper3') # 28
res3 = func3(*args, **kwargs) # 29 调用index函数
return res3 # 32
return wrapper3 # 8.返回wrapper3
@outter1 # 17.outter1(warpper2)
# 22.接收返回值warpper1,此时函数名warpper1上面没有语法糖index=outter1(warpper2)
# 23.index其实是warpper1,调用函数warpper1
@outter2 # 10.outter2(warpper3)
# 16.接收返回值warpper2,此时函数名warpper2上面还是语法糖warpper2=outter2(warpper3)
@outter3 # 4.这一步实际是outter3(index)
# 9.接收返回值warpper3,此时函数名warpper3上面还是语法糖 warpper3=outter3(index)
# 语法糖的功能:会自动将下面紧挨着的函数名当作参数传递给@符号后面的函数名
# @outter1
# @outter2
# @outter3
def index():
print('from index') # 31
index() # 30
有参装饰器
- 有参装饰器是为了给装饰器传递额外参数
- 需求:在装饰器内部可以切换多种数据来源来比对用户数据
def outer(condition,type_user):
def login_auth(func_name): # 这里不能再填写其他形参
def inner(*args, **kwargs): # 这里不能再填写非被装饰对象所需的参数
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 应该根据用户的需求执行不同的代码
if type_user =='jason':print('VIP')
if condition == '列表':
print('使用列表作为数据来源 比对用户数据')
elif condition == '字典':
print('使用字典作为数据来源 比对用户数据')
elif condition == '文件':
print('使用文件作为数据来源 比对用户数据')
else:
print('去你妹的 我目前只有上面几种方式')
return inner
return login_auth
@outer('文件','jason')
def index():
print('from index')
index()
递归函数
- python允许函数最大递归的调用的次数是1000次,
- 自己验证会有所偏差在996左右,自定义最大调用次数为2000
- 函数直接或者间接调用了自己就被称为递归调用
直接调用
def index():
print('随便的内容')
index()
index()
# 间接调用
def index():
print('随便的内容')
home()
def home():
print('不随便的样式')
index()
home()/index()
递归函数可用来推导一个循环有结果的事件。
递归函数每次循环都会比上一次循环简单
递归函数最终要有一个明确的结束条件
递归函数练习
l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
def get_num(l1): #1 定义函数get_num
#3 执行get_num内部代码
for i in l1: #4 for循环在l1里面的数据值
if isinstance(i, int): #5 判断i数据值是整型,
# isinstance(object, classinfo)是Python中的一个内置函数,用来判断一个对象的变量类型,
# #object位置是实例对象,classinfo是直接或间接类名、基本类型或者由它们组成的元组
print(i) # 6是整型打印
else: # 5判断i数据值不是整形
get_num(i) # 6再次调用get_num函数再次进行传值
get_num(l1) # 2 调用函数get_num,给函数get_num传入形参l1列表
算法:二分法
l1 = [11, 23, 32, 45, 65, 78, 90, 123, 432, 467, 567, 687, 765, 876, 999, 1131, 1232]
def index(l1,target_num): #1.定义函数index(),位置参数l1,关键字参数target_num
#2.3此时相当于给l1传值了一个列表,给target_num赋值了target_num = 999
if len(l1) == 0: #3.判断l1内的数据值是否为零,为零说明没有这个数。直接结束程序
print('找不到')
return
middle_index = len(l1) // 2 #4.统计l1数据集的个数然后
middle_value = l1[middle_index] #5.获取l1列表中间的数
if target_num > middle_value: #6.判断进入分支
# 判断大小,如果要找的数比我们得到的数大,说明要找的数在右边
right_l1 = l1[middle_index + 1:] #6.1.对整个列表切片,得到列表判断完右边的所有数据值
# +1不包括自身顾头不顾尾"""
print(right_l1) #6.2.输出获取刚才得到的切片后的列表
index(right_l1,target_num) #6.3.再次调用index函数给其进行传值操作
elif target_num < middle_value: #6.判断进入分支
# 判断大小,如果要找的数比我们得到的数小,说明要找的数在左边
left_l1 = l1[:middle_index] #6.1对整个列表切片,得到列表判断完左边的所有数据值
# ,不用+1,最右边的数据值不包括在内。
print(left_l1) #6.2输出获得刚才得到的切的列片后表
index(left_l1,target_num) #6.3.再次调用index函数给其进行传值操作
else:
print('找到了') #6.如果上面条件都不成立,说明要查找的数就是切分完中间的数,
index(l1,999) #2.1调用index函数,将l1传给被定义的函数index位置形参,
#2.2 将999传给target_numc传给被定义的index的关键字行参
- 二分法只能判断已经排好序的数据集,并且在某些查找某些开头或结尾的数值效率不高