装饰器
今日内容总结
多层语法糖
多层语法糖>>>:加载顺序由下而上
每次执行之后如果上面还有语法糖 则直接将返回值函数名传给上面的语法糖
如果上面没有语法糖了 则变形 index = outer1(wrapper2)
def outer1(func1): # func1 = wrapper2
print('加载了outer1')
def wrapper1(*args, **kwargs):
print('执行了wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def outer2(func2): # func2 = wrapper3
print('加载了outer2')
def wrapper2(*args, **kwargs):
print('执行了wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def outer3(fun3): # func3 = index
print('加载了outer3')
def wrapper3(*args, **kwargs):
print('执行了wrapper3')
res3 = fun3(*args, **kwargs)
return res3
return wrapper3
@outer1 # index = outer1(wrapper2) 返回值是wrapper1
@outer2 # outer2(wrapper3) 返回值是wrapper2
@outer3 # outer3(index函数) 返回值是wrapper3
def index():
print('666')
index()
有参装饰器
# 校验用户是否登录装饰器
def outer(mode):
def login_auth(func_name):
def inner(*args, **kwargs):
username = input('username>>>:').strip()
password = input('password>>>:').strip()
if mode == '1':
print('跟定义好的结果比对 数据值直接写死')
elif mode == '2':
print('打开文本文件 一行行读取比对')
elif mode == '3':
print('跟提前定义好的字典 比对')
elif mode == '4':
print('数据来源于MySQL')
return inner
return login_auth
"""当装饰器中需要额外的参数时>>>:有参装饰器"""
"""
函数名加括号执行优先级最高 有参装饰器的情况
先看函数名加括号的执行
然后再是语法糖的操作
"""
@outer('1')
def index():
print('from index')
index()
@outer('2')
def func():
print('from func')
func()
装饰模板器
# 最常用的无参装饰器
def outer(func_name):
def inner(*args, **kwargs):
res = func_name(*args, **kwargs)
return res
return inner
@outer
def index():
pass
# 不常用的有参装饰器
def outer_plus(mode):
def outer(func_name):
def inner(*args, **kwargs):
res = func_name(*args, **kwargs)
return res
return inner
return outer
@outer_plus('MySQL')
def func():
pass
装饰器修复技术
from functools import wraps # 修复技术固定代码
def outer(func_name):
@wraps(func_name) # 仅仅是为了让装饰器的效果更加逼真
def inner(*args, **kwargs):
"""我是inner 我擅长让人蒙蔽"""
res = func_name(*args, **kwargs)
return res
return inner
@outer
def func():
"""我是真正的func 我很强大 我很牛 我很聪明"""
pass
help(func)
print(func)
递归函数
1.函数的递归调用
函数直接或者间接的调用了函数自身
直接调用
def index():
print('from index')
index()
index()
间接
def index():
print('from index')
func()
def func():
print('from func')
index()
func()
'''最大递归深度:python解释器添加的安全措施'''
count = 0
def index():
global count
count += 1
print(count)
index()
index()
'''官网提供的最大递归深度为1000 我们在测试的时候可能会出现996 997 998'''
2.递归函数
1.直接或者间接调用自己
2.每次调用都必须比上一次简单
并且需要有一个明确的结束条件
递推: 一层层往下
回溯: 基于明确的结果一层层往上
"""
get_age(5) = get_age(4) + 2
get_age(4) = get_age(3) + 2
get_age(3) = get_age(2) + 2
get_age(2) = get_age(1) + 2
get_age(1) = 18
"""
def get_age(n):
if n == 1:
return 18
return get_age(n - 1) + 2
res = get_age(5)
print(res)
作业
# 1.利用递归函数依次打印列表中每一个数据值
# l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
l1 = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]]
def get_list(li): # 定义一个函数 需要用户传一个列表
for i in li: # 遍历用户传来的列表
if type(i) == list: # 判断遍历来的数据值的数据类型是否是列表
get_list(i) # 是列表继续调用函数并传参遍历出来的列表 递归函数
else:
print(i) # 不是列表就打印出数据值
get_list(l1)
# 有参装饰器编写多种用户登录校验策略
l2 = [['qyf', '123'], ['wei', '234']]
d1 = {'qyf': {'name': 'qyf', 'pwd': '222'}, 'wei': {'name': 'wei', 'pwd': '333'}}
def outer(a):
def login_auth(func):
def inner(*args, **kwargs):
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if a == '1':
if username == 'qyf' and password == '123':
print('登陆成功')
res = func(*args, **kwargs)
return res
print('用户名或密码错误')
elif a == '2': # 列表
for i in l2:
if username == i[0] and password == i[1]:
print('登陆成功')
res = func(*args, **kwargs)
return res
print('用户名或密码错误')
elif a == '3': # 字典
if username in d1:
b = d1.get(username)
name, pwd = b.values()
if username == name and password == pwd:
print('登陆成功')
res = func(*args, **kwargs)
return res
print('用户名或密码错误')
elif a == '4':
with open('text', 'r', encoding='utf8') as f:
for i in f:
name, pwd = i.strip().split('|')
if username == name and password == pwd:
print('登陆成功')
res = func(*args, **kwargs)
return res
print('用户名或密码错误')
else:
print('没有')
return inner
return login_auth
@outer('3')
def login():
print('登录功能')
login()