函数的进阶一
1. 闭包函数
-
闭包函数:闭包函数把闭包函数内部的变量 +闭包函数内部的函数 这两者包裹在一起,然后通过返回值的形式返回处来。
这样一来,就能在全局进行对闭包函数内部的函数的调用
-
闭包函数至少得符合函数的嵌套
def f1(url): #f1就是闭包函数
def spider():
print(url)
return spider #函数对象
taobao = f1('www.taobao.com') #这里的 taobao 就是函数 spider
taobao() #打印结果: www.taobao.com
2 .装饰器
(1)二层装饰器
-
装饰器就是对闭包函数的高级应用
-
装饰器的性质和特点:
-
装饰器的本质就是一个函数
-
装饰器的功能就是给被装饰的函数增加功能,增加功能是必须满足一下两点
- 不改变被装饰函数的源代码
- 不改变被装饰函数的调用方式(就是说以前用 f1() 调用,装饰之后还用 f1() 调用,被装饰函数有多少形参,装饰后,调用f1()时,其括号中也得有多少实参,不能多也不能少)
-
-
下面的例子是登陆装饰器
def zhuangshi(func): # 接收到值后,func 就是函数: hanshu
def login(*args, **kwargs):
while True:
user_inp = input('请输入用户名:')
pwd_inp = input('请输入密码:')
with open('user_info.txt', 'r', encoding='utf8')as fr:
for user_info in fr:
user_name, pwd = user_info.strip().split(':')
if user_inp == user_name and pwd_inp == pwd:
print('登陆成功')
res = func(*args, **kwargs)
return res
else:
print('登录失败')
return login
@zhuangshi # 双层装饰器,实现了:hanshu = zhuangshi(hanshu),必须放在被装饰函数的上一行
def hanshu(x, y):
return x + y
print(hanshu(10, y=20))
(2)三层装饰器
-
就是在双层的外面再加一层函数
在下面再return 一次第二层函数
-
三层装饰器实现了向装饰器中传参事物功能
username_list = []
def sanceng(role):
def login_deco(func):
def wrapper(*args, **kwargs):
if username_list:
print('已经登录,请勿重复登录')
res = func(*args, **kwargs)
return res
username_inp = input('请输入用户名:')
pwd_inp = input('请输入密码:')
with open(f'{role}_info.txt', 'r', encoding='utf8') as fr: #选课系统中判断是哪一种登陆 :role为老师、学生和管理员
for user_info in fr:
username, pwd = user_info.strip().split(':')
if username_inp == username and pwd_inp == pwd:
print('登录成功')
username_list.append(username)
res = func(*args, **kwargs)
return res
else:
print('登录失败')
return wrapper
return login_deco
@sanceng('user')
def index(x, y):
print('index')
print('x,y', x, y)
return 123
res = index(10, 20)
print(res)
(3)装饰器模板
# 二层装饰器模板
def deco(func):
def wrapper(*args, **kwargs):
# 要加什么功能就加上去
res = func(*args, **kwargs)
return res
return wrapper