装饰器的用法与递归函数
多层装饰器
1.语法糖执行时,会将返回值赋值给下面紧跟的函数
2.如果是连续的语法糖,语法糖会从下到上执行,并将返回值赋值给上一层函数,直到最顶层函数返回值会赋值给下面的函数
def info2(a2): # 定义info2函数
print('运行info2')
def sre2(*args, **kwargs):
print('运行ser2')
a2(*args, **kwargs) # 执行sre1函数
return
return sre2 # 返回sre2函数名
def info1(a1): # 定义info1函数
print('运行info1')
def sre1(*args, **kwargs):
print('运行ser1')
a1(*args, **kwargs) # 执行sre函数
return
return sre1 # 返回sre1函数名
def info(a): # 定义info函数
print('运行info')
def sre(*args, **kwargs):
print('运行ser')
a(*args, **kwargs) # 执行func函数
return
return sre # 返回sre函数名
@info2 # func = info2(sre1) 执行info2函数并将sre1传给a2,返回sre2
@info1 # sre1 = info1(sre) 执行info1函数并将sre传给a1,返回sre1
@info # sre = info(func) 执行info函数并将func传给a,返回sre
def func(): # 定义func函数
print('运行func')
func() # 执行sre2
"""run:
运行info
运行info1
运行info2
运行ser2
运行ser1
运行ser
运行func
"""
有参装饰器
"""
如果装饰器需要不同的参数来执行不同的代码,我们可以在装饰器外面在闭包一层函数,无论需要多少参数,通过这层函数都可以传参数进去
"""
def outer(data_source):
print('运行outer')
def info(a):
print('运行info')
def sre(*args, **kwargs):
if data_source == 'list':
print('使用列表数据进行用户数据对比')
a(*args, **kwargs)
elif data_source == 'dict':
print('使用字典数据进行用户数据对比')
a(*args, **kwargs)
elif data_source == 'file':
print('使用文件数据进行用户数据对比')
a(*args, **kwargs)
else:
print('没有此功能')
return sre
return info
@outer('list')
def func():
print('数据对比成功')
func()
"""run:
运行outer
运行info
使用列表数据进行用户数据对比
数据对比成功
"""
@outer('dict')
def func1():
print('数据对比成功')
func1()
"""run:
运行outer
运行info
使用字典数据进行用户数据对比
数据对比成功
"""
@outer('file')
def func2():
print('数据对比成功')
func2()
"""run:
运行outer
运行info
使用文件数据进行用户数据对比
数据对比成功
"""
递归函数
-
递归调用(直接调用)
在调用函数时直接调用函数自己,如此反复循环
def func():
print('运行func')
func()
func()
-
递归调用(间接调用)
在调用a函数时调用b函数,b函数在调用a函数,如此反复循环
def func():
print('运行func')
index()
def index():
print('运行index')
func()
func()
- 函数的递归循环次数是有限制的
count = 0
def func():
print('运行func')
global count
count += 1
print(count)
func()
func() # run最后为996
"用代码计算函数的递归次数与官方给出的限制有一点差别"
import sys
print(sys.getrecursionlimit()) # run:1000 获取最大递归次数
sys.setrecursionlimit(666) # 自定义最大递归次数
print(sys.getrecursionlimit()) # run:666
-
递归函数可以用于递推与回溯
1.递推:一层一层的寻找所要的数据
2.回溯:根据已知条件推导最后的结果
1.每次调用时都必须比上一次调用简单,并且递归函数必须要有结束条件
"将下面的列表里所有的数据值依次打印出来"
aa = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12]]]]]]]]]]]]
def count(aa):
for i in aa:
if isinstance(i, int):
print(i)
else:
count(i)
count(aa)
算法之二分法
- 二分法
1.算法就是计算机面对一个问题的解决方法,它没有最优解,只有更好的算法
2.算法有好几类,而二分法是所有算法里面最简单的算法
- 二分法使用
'用二分法查找数据是否在数据容器内,这个数据容器必须是有序的'
l1 = [11, 23, 32, 45, 65, 78, 90, 123, 432, 467, 567, 687, 765, 876, 999, 1131, 1232]
def func(l1, target):
if len(l1) == 0:
print('找不到该数据值')
return
middle = len(l1) // 2
median = l1[middle]
if target > median:
right_l1 = l1[middle + 1:]
print(right_l1)
func(right_l1, target)
elif target < median:
left_l1 = l1[:middle]
print(left_l1)
func(left_l1, target)
else:
print('找到了', target)
func(l1, 999)
"""run:
[467, 567, 687, 765, 876, 999, 1131, 1232]
[999, 1131, 1232]
[999]
找到了 999
"""
作业
1
data_list = ['barry', '123']
def outer(data_source):
def info(a):
def sre(*args, **kwargs):
if data_source == 'list':
name = input('输入用户名>>>:').strip()
password = input('输入密码>>>:').strip()
if name in data_list and password in data_list:
a(*args, **kwargs)
else:
print('用户名或密码错误')
return
elif data_source == 'file':
name = input('输入用户名>>>:').strip()
password = input('输入密码>>>:').strip()
with open(r'a.txt', 'r', encoding='utf8')as f:
for i in f:
name_info, password_info = i.split('|')
if name in name_info and password in password_info:
a(*args, **kwargs)
else:
print('用户名或密码错误')
return
else:
print('没有此功能')
return sre
return info
@outer('list')
def func():
print('用户登录成功')
func()
@outer('file')
def func2():
print('用户登录成功')
func2()
2
推导指定某个人的正确年龄
eg: A B C D E 已知E是18 求A是多少
'''ABCDE的年龄依次递减1岁'''
name = ['E', 'D', 'C', 'B', 'A']
count = 18
def age():
global count
for i in name:
if i == 'A':
print(count)
else:
count += 1
age()

浙公网安备 33010602011771号