函数(多层语法糖,有参装饰器、递归函数)
函数
装饰器语法糖
"""装饰器语法糖,语法糖会自动将下面紧挨着的函数当作第一个参数自动传给@函数调用"""
def outer(func):
def inner(*args,**kwargs):
print('执行被装饰对象之前可以做的额外操作')
res = func(*args,**kwargs)
print('执行被装饰对象之后可以做的额外的操作')
return res
return inner
@outer
def func():
print('和叶')
return 'func'
@outer
def func1():
print('和花')
return 'func1'
func()
func1()
多层语法糖
语法糖的结构如下
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()
""" 多层语法糖 加载顺序由下往上,
每次执行之后,如果上面还有语法糖,则直接将返回值函数传给上面的语法糖,
如果上面没有语法糖了,则变形index= outter1(wrapper2)
"""
语法糖解析顺序如下
有参装饰器
# 校验用户是否登录装饰器
def outer(mode):
def login_auth(func):
def inner(*args,**kwargs):
username = input('please input your name>>:').strip()
password = input('please input your pwd>>:').strip()
if mode == '1':
print('数据直接写死')
elif mode == '2':
print('数据来源于文本文件')
elif mode == '3':
print('数据来源于字典')
elif mode == '4':
print('数据来源于MySQL')
# res = func(*args,**kwargs)
# return res
return inner
return login_auth
# @outer('1')
# def index():
# print('from index')
# index() # 数据直接写死
# @outer('2')
# def index():
# print('from index')
# index() # 数据来源于文本文件
@outer('3')
def index():
print('from index')
index() # 数据来源于字典
装饰器模板
最常用的无参模板
"""无参装饰器"""
def outer(func):
def inner(*args,**kwargs):
print("在执行被装饰对象之前可以做的额外的操作")
res = func(*args,**kwargs)
print("在执行被装饰对象之后可以做的额外的操作")
return res
return inner
@outer
def index():
pass
不常用的有参装饰器
def outer_plus(mode):
def outer(func):
def inner(*args,**kwargs):
print("在执行被装饰对象之前可以做的额外的操作")
res = func(*args,**kwargs)
print("在执行被装饰对象之后可以做的额外的操作")
return res
return inner
return outer
@outer_plus('MySQL')
def index():
pass
装饰器修复技术
help函数名来查看函数的文档注释,本质就是查看函数的_doc_属性。但被装饰之后的函数,查看文档注释
"""help的用法"""
def index():
pass
help(index)
"""打印结果:
Help on function index in module __main__: index()
"""
help(len)
"""打印结果:
# Help on built-in function len in module builtins:
len(obj, /)
Return the number of items in a container.
"""
引入了functools模块下提供一个装饰器wraps专门来我们实现
from functools import wraps
def outer(func):
@wraps(func) # 仅仅时为了让装饰器的效果更加逼真,平时不用写
def inner(*args,**kwargs):
""" 我是inner 我擅长让人蒙蔽"""
res = func(*args,**kwargs)
return res
return inner
@outer
def index():
"""我是真正的index"""
pass
help(index)
help(index)
index()
递归函数
1.函数的递归调用
函数直接或者间接的调用了函数自身
1.1直接调用
# 直接调用
def index():
print('from index')
index()
index()
1.2间接调用
# 间接调用
def index():
print('from index')
func()
def func():
print('from func')
index()
func()
2.最大递归深度
eg:
count = 0
def index():
global count
count += 1
print(count)
index()
index() # 1-996
""" 最大递归深度:python解释器添加的安全措施"""
""" 官网提供的最大递归深度为1000,我们在测试的时候可能会出现996、997、998"""
3.递归函数
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,]]]]]]]]
方法1
def func(a):
for i in a:
if type(i) is int:
print(i)
else:
return func(i)
func(l1)
方法2
def func(a):
for i in a:
if isinstance(i,int):
print(i)
else:
return func(i)
func(l1)
2.利用有参装饰器编写多种用户登录校验策略
dict_list = {'1':{'name':'kiki','password':"123"},
'2':{'name':'kimi','password':"456"}}
def outer_plus(mode):
def outer(func):
def inner(*args,**kwargs):
username = input('please input your name>>:').strip()
password = input('please input your pwd>>:').strip()
if mode == '1':
print('数据直接写死')
elif mode == '2':
with open(r'a.txt','r',encoding='utf8') as f:
for line in f:
real_name,real_pwd = line.split('|')
if username == real_name and password == real_pwd.strip('\n'):
print('数据来源于文本文件')
res = func(*args, **kwargs)
return res
else:
print('用户名不存在')
elif mode == '3':
for i in dict_list:
if dict_list[i]['name'] == username and dict_list[i]['password']==password:
print('数据来源于字典')
res = func(*args, **kwargs)
return res
else:
print('用户名不存在')
elif mode == '4':
print('数据来源于MySQL')
res = func(*args,**kwargs)
return res
return inner
return outer
@outer_plus('3')
def index():
print('校验成功')
index()