一、闭包:
1.条件:(1)外部函数中定义了内部函数
(2)外部函数是有返回值
(3)返回的值是:内部函数名
(4)内部函数引用了外部函数的变量
格式:
def 外部函数():
......
def 内部函数():
......
return 内部函数
2.闭包的作用:
(1)保存返回闭包时的状态(外层函数变量)
(2)由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存。
(3)闭包内部函数可以同级访问
3.闭包的例子:计数器
#计数器
def generate_count():
container = 0
def add_one():
nonlocal container
container += 1
print('当前是第{}次访问'.format(container))
return add_one
counter = generate_count()
counter()
counter()
counter()
输出结果:
二、装饰器
1.特点:(1)函数A作为参数出现的(函数B接收函数A)
(2)有闭包的特点
(3)如果装饰器是多层的,谁距离函数最近就优先使用哪个装饰器
2.小例子:
def decorate(func):
def wrapper(*args,**kwargs): #()元组和{}字典
print('正在校验中...')
print('校验完毕...')
#调用原函数
func(*args,**kwargs)
return wrapper
@decorate
def f3(students,time='2018'):
for stu in students:
print(stu)
print(time)
students = ['lily','petter','tom']
f3(students)
注意:当在函数f3上面写@decorate时,就相当于执行了 f3 = decorate(f3),f3变量就指向了wrapper函数所在内存地址,当执行
f3()时,就相当于执行wrapper()。
输出结果:
3.带参数的装饰器
#装饰器带参数
def outer(a): #第一层:负责接收装饰器参数的
def decorate(func): #第二层:负责接收函数的
def wrapper(*args,**kwargs): #第三层:负责接收函数的参数
func(*args)
print("--->铺地砖{}块".format(a))
return wrapper #返回:第三层
return decorate #返回:第二层
@outer(10)
def house(time):
print('我{}日期拿到房子钥匙,是毛坯房...'.format(time))
house('2020-8-6')
输出结果:
4.装饰器的简单应用:
#开发:登录验证
import time
islogin = False
#定义一个登录函数
def login():
username = input('输入用户名:')
password = input('输入密码:')
if username=='tata' and password == 'honey':
return True
else:
return False
#定义一个装饰器,进行付款验证
def login_required(func):
def wrapper(*args,**kwargs):
global islogin
print('-----付款------')
#验证用户是否登录
if islogin:
func(*args,**kwargs)
else:
#跳转到登录页面
print('用户没有登录,不能付款')
islogin = login()
print(f'登录状态:{islogin}')
return wrapper
@login_required
def pay(money):
print('正在付款,付款金额为{}元'.format(money))
print('付款中...')
time.sleep(2)
print('付款完成')
if __name__ == '__main__':
pay(10000)
pay(8000)
输出结果:
感谢哔站上千峰教育提供的python学习视频!