python基础——闭包函数和生成器

欢迎关注,敬请点赞!

python基础——闭包函数和生成器

闭包函数

定义

  • 外部函数中定义一个内部函数
  • 内部函数中使用外部函数的局部变量
  • 外部函数将内部函数作为返回值返回
  • 返回的函数就称为闭包

【定义函数】

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关键字
    【生成器函数调用方法:】
  1. 不结合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>
  1. 函数模式调用,每次用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
  1. 对象模式调用,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!
  1. 对象模式调用,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需要在生成器启动后,才能传递数值。

欢迎关注,敬请点赞!
返回顶部

原创文章 43 获赞 14 访问量 2845

猜你喜欢

转载自blog.csdn.net/weixin_45221012/article/details/105819998