欢迎关注,敬请点赞!
闭包函数
定义
- 外部函数中定义一个内部函数
- 内部函数中使用外部函数的局部变量
- 外部函数将内部函数作为返回值返回
- 返回的函数就称为闭包
【定义函数】
def outer():
sum = 0
# 外部函数里面定义一个内部函数
def inner(a_in):
# 内部函数中使用外部函数的局部变量
nonlocal sum # 在内部函数中使用外部函数的局部变量,需要使用nonlocal声明
sum += a_in
return sum
# 外部函数将内部函数作为返回值返回
return inner # 不加括号,返回的函数就称为闭包
【调用函数】
s_custom = outer # s_custom实际上就是inner()
print(s_custom(10))
# 运行结果:10
print(s_custom(20))
# 运行结果:30
小结:
- 闭包就是一个具有执行环境的函数。
生成器
使用场景
在使用列表时,数据量特别大,内存占用会突然增大,使用时又不需要一下子使用全部,通常都是一个一个使用,为了解决这个问题,python中引入了生成器的概念。
使用方式
- 方式1:将列表生成式的[]换成()
lt = [i for i in range(10)] # 列表生成式
print(lt)
# g就是生成器
g = (i for i in range(10))
# print(g)
- 方式2:在函数中使用yield关键字
【生成器函数调用方法:】
- 不结合next不调用
def generator():
print('begin test')
a = yield 10
print('a = ', a)
b = yield 20
print('b = ', b)
print('end test!')
print(generator())
# 运行结果:
# <generator object generator at 0x0000018D8F15E648>
- 函数模式调用,每次用next调用生成器都是从头开始
def generator():
print('begin test')
a = yield 10
print('a = ', a)
b = yield 20
print('b = ', b)
print('end test!')
# yield后面的内容会返回,执行到yield后会停止
print(next(generator()))
# 运行结果:
# begin test
# 10
print(next(generator()))
# 运行结果仍然为:
# begin test
# 10
- 对象模式调用,next每次向后获取一个元素
def generator():
print('begin test')
a = yield 10
print('a = ', a)
b = yield 20
print('b = ', b)
print('end test!')
g = generator() # 生成器对象
# yield后面不执行,和return一样;
print(next(g))
# 运行结果:
# begin test
# 10
# 只有当next推进时,才往后执行
print(next(g))
# 运行结果:
# a = None
# 20
try:
print(next(g))
except:
pass
# 运行结果:
# b = None
# end test!
- 对象模式调用,send需要在生成器启动后,才能传递数值
返回顶部
【错误用法:】
def generator():
print('begin test')
a = yield 10
print('a = ', a)
b = yield 20
print('b = ', b)
print('end test!')
g = generator()
print(g.send(5))
# 报错:
# TypeError: can't send non-None value to a just-started generator
# 在一个生成器函数未启动之前,是不能传递数值进去
【正确用法:】
def generator():
print('begin test')
a = yield 10
print('a = ', a)
b = yield 20
print('b = ', b)
print('end test!')
g = generator()
print(next(g))
# 运行结果:
# begin test
# 10
print(g.send(5)) # 数据传进去赋值给a
# 运行结果:
# a = 5
# 20
try:
print(g.send(15)) # 数据传进去赋值给b
except:
pass
# 运行结果:
# b = 15
# end test!
小结:
- 函数模式调用,每次用next调用生成器都是从头开始。
- 对象模式调用,next每次向后获取一个元素。
- 对象模式调用,send需要在生成器启动后,才能传递数值。
欢迎关注,敬请点赞!
返回顶部
转载:https://blog.csdn.net/weixin_45221012/article/details/105819998
查看评论