python之生成器
发布日期:2021-05-04 19:07:23 浏览次数:22 分类:技术文章

本文共 2489 字,大约阅读时间需要 8 分钟。

python之生成器

文章目录

一、生成器介绍

什么是生成器( generator

  • 生成器就是一个自定义迭代器
  • 函数体内含有yield关键字

为何要用生成器?

  • 为了节省内存

创建生成器的两种方式

  • 调用yield关键字
  • 使用生成器表达式

如何用生成器

函数体内但凡出现yield关键字,调用函数将不会触发函数体代码的运行,而是会返回一个生成器对象,生成器本质就是一个迭代器

二、生成器与yield

如何得到自定义的迭代器

在函数内定义yield关键字, 调用函数并不会执行完函数体代码, 会返回一个生成器对象(生成器就等同于迭代器)

注意:

一旦函数体内出现yield关键字, 再去调用函数, 就和函数体代码没有关系了, 得到的就是一个生成器, 你的函数体代码的生效, 取决与你的next

示例

def func():    yield 1    yield 2    yield 3res_generator = func()# 返回一个生成器对print(res_generator)  # 
# 生成器就等同于迭代器, 也有迭代器下的内置方法__iter__(),__next__(), 也有iter()和next()功能res_generator.__iter__()iter(res_generator)# res_generator.__next__()# next(res_generator)# 对定义yield关键字的函数,返回的生成器对象迭代取值res1 = res_generator.__next__()print(res1) # 1res2 = res_generator.__next__()print(res2) # 2res3 = res_generator.__next__()print(res3) # 3# 补充: 之前我们使用的len()功能, 内部其实最后调用的还是内置的__len__()方法res = len('aaa') print(res) # 3res = 'aaa'.__len__()print(res) # 3# 需求(实例): 实现range功能def my_range(start, stop, step=1): print("start...") while start < stop: yield start start += step print("stop...")res = my_range(0, 10)print(res)for item in res: print(item) #
'''start...0123456789stop...'''

yield 与 return 的区别

  1. 相同点
    • 在返回值的及的角度,用法都一样
  2. 不同点
    • yield 可以返回多次值, 而 return 只能返回一次值

总结yield

  • 为我们提供了一种自定义的迭代器的方式
  • yield 可以暂停函数, 保存函数执行的状态, 然后使用 next 方法再次触发函数体代码的运行 (协程知识点)

示例应用:

  • 造一个无穷值

    def my_range():	n = 0	while True:		yield n		n += 1obj = my_range()    # 一个生成器print(obj)          # 
    输出的是老母鸡内存地址# 使用"next"取值print(next(obj)) # 0print(next(obj)) # 1print(next(obj)) # 2print(next(obj)) # 3 ......等等..# 使用 "for" 循环for i in my_range(): # 也可以使用 for 循环取 print(i)
  • 模仿内置函数range()

    def my_range(start, stop, step = 1):	n = start	while n < stop:		yield n		n += step# 使用 "next" 取值obj = my_range(2 ,14, 2)print(next(obj))     # 2print(next(obj))     # 4print(next(obj))     # 6# 使用 "for" 循环for line in my_range(2, 15, 3):	print(line)

yield 的应用

  • next : 执行一次
  • send : send 会传送一个值给 yield 关键字, 赋值给 yield 左边的的变量名, 再执行等同于 next 的功能继续执行下面的代码
  • close : 当使用 close 时, 会关闭生成器, 无法在进行迭代取值, 取值则报 StopIteration 异常
  • 喂狗示例: ps : “dog.send(None)” 的效果等于 “next(dog)
def eat(name):	print('%s start eat' %name)	while True:		food = yield 1  # yield 接收 send 传过来的值赋值给 food		print('%s start eat %s'%(name,food))dog = eat('派大星的狗')   # 获得生成器next(dog)                # 派大星的狗 start eatdog.send("淘小欣")      # 派大星的狗 start eat 淘小欣  (send 自带 next 的执行功能)dog.close()              # 关闭这个生产器 (无法在进行取值)next(dog)                # 再次取值跑出异常 "StopIteration"
上一篇:python之三元表达式、生成式、生成器表达式
下一篇:python之迭代器

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年03月15日 22时16分12秒