闭包函数
实例:满足打印欢迎各位学生前来学习包含姓名,性别,及年龄,年龄需要每年纪都发生变动
"""
闭包函数
"""
def student_grade(grade):
def print_welcome(name, gender):
print(f"欢迎各位学生前来学习,欢迎{grade}年纪的{name}{gender}同学")
return print_welcome
student_list = student_grade(1)
student_list('harry', '男')
student_list('hemin', '女')
student_list('rowan', '男')
简而言之, 闭包的特点就是内部函数引用了外部函数中的变量。 在Python中,支持将函数当做对象使用,也就是可以将一个函数当做普通变量一样用作另一个函数的参数和返回值。拥有此类特性的语言,一般都支持闭包。
闭包中被内部函数引用的变量,不会因为外部函数结束而被释放掉,而是一直存在内存中,知道内部函数被调用结束。
def func():
name = 'python'
def inner():
print(name)
return inner
f = func() # f = func() = inner
f() # f() = inner
# 输出结果:python
装饰器
#第一步定义一个闭包函数
def timer(func):
def inner():
print('函数开始执行')
print(func)
#func代表函数对象类似于指针,而不是指针指向的内容,要想获取到指针指向的内容,要用func()
print('函数结束执行')
#第二步返回内部函数
return inner
@timer
#第三步使用装饰器默认将函数对象传入闭包函数中
def hogwarts():
print('hogwarts')
#第四步调用函数对象,执行函数功能
hogwarts()
运行结果是:<function hogwarts at 0x10a950820>
装饰器-实战练习
实现一个计时器的装饰器,计算函数执行时间
写装饰器三步曲:
step1:定义一个外部函数,外函数有一个形参,接受被装饰的函数对象
step2:定义一个内部函数,内部函数内调用传入函数
step3:外部函数返回调用函数对象
import datetime
def timer(func):
#内部函数传入参数
def inner(name):
print('函数开始执行')
start_time = datetime.datetime.now()
#这个地方仍然需要加上形参
func(name)
print('函数结束运行')
end_time = datetime.datetime.now()
print(f'该函数总计使用时常为:{end_time-start_time}')
return inner
@timer
def hogwarts(name):
#被装饰的函数有参数传入
print(f'我真是个大帅哥{name}')
hogwarts('harry')
运行结果是:
函数开始执行
我真是个大帅哥harry
函数结束运行
该函数总计使用时常为:0:00:00.000014
tips:
当被装饰的函数存在参数,则需要在内部函数传入形参,并在函数调用时传入参数
如果写死一个参数,但是无法确定被装饰函数的参数数量,这种会报错
解决方案是:将内部函数的形参及内部函数调用函数对象时传入形参
import datetime
def timer(func):
#内部函数传入参数为该参数,可以不用在意被装饰函数有几个形参传入
def inner(*args,**kwargs):
print('函数开始执行')
start_time = datetime.datetime.now()
#这个地方仍然需要加上形参
func(*args,**kwargs)
print('函数结束运行')
end_time = datetime.datetime.now()
print(f'该函数总计使用时常为:{end_time-start_time}')
return inner
@timer
def hogwarts(name):
#被装饰的函数有参数传入
print(f'我真是个大帅哥{name}')
@timer
def hogwarts2(name,age,gender):
print(f'{name}为{age}岁的{gender}孩真好看')
hogwarts('harry')
hogwarts2('rowan',11,'男')