生成器
可迭代对象、迭代器、生成器
- 可迭代对象:实现了方法__iter__或__getitem__就是可迭代的。
- 迭代器:在可迭代对象的基础上实现了__next__方法,__iter__方法需返回一个迭代器,如果自身是迭代器则返回self。
- 生成器:可以理解为在迭代器的基础上再实现了yield,yield返回新的值后,会在当前位置阻塞,等待下一次的调用。
如何激活生成器
- next()
- generator.send(None)
生成器的执行状态
- GEN_CREATED
- GEN_RUNNING
- GEN_SUSPENDED
- GEN_CLOSED
生成器的异常处理
当生成器不满足生成元素的条件时,就应该抛出异常StopIteration
从生成器过度到协程
协程是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序。
如何向生成器中发送消息:
1 | def jumping_range(N): |
重点在于jump = yield index
yield index
是将indexreturn
给外部调用程序jump = yield
是可以接收外部程序通过send()发送的信息,并赋值给jump
yield from 语法
为什么要使用协程
如果没有协程,要去实现一个并发程序,可能会有以下问题
- 使用最常规的同步编程要实现异步并发效果并不理想,或者难度极高
- 由于GIL锁的存在,多线程的运行需要频繁的加锁解锁,切换线程,这极大的降低了并发性能
而协程的出现,刚好可以解决以上的问题,它的特点有
- 协程是在单线程里实现任务的切换的
- 利用同步的方式去实现异步
- 不再需要锁,提高了并发性能
yield from用法详解
yield from 是在python3.3才出现的语法。这个特性是在python2中没有的。
yield from 后面是需要加可迭代对象,它可以普通的可迭代对象,也可以是迭代器,甚至是生成器。
1 | # usage: yield |
生成器嵌套
- 调用方:调用委托生成器的客户端代码
- 委托生成器:包含yield from的表达式生成器函数
- 子生成器:yield from 后面加的生成器函数