python特性(八):生成器对象的send方法
2017-02-21 19:57
375 查看
生成器对象是一个迭代器。但是它比迭代器对象多了一些方法,它们包括send方法,throw方法和close方法。这些方法,主要是用于外部与生成器对象的交互。本文先介绍send方法。
send方法有一个参数,该参数指定的是上一次被挂起的yield语句的返回值。这样说起来比较抽象,看下面的例子。
输出的结果如下
上面代码的运行过程如下。
当调用gen.next()方法时,python首先会执行MyGenerator方法的yield 1语句。由于是一个yield语句,因此方法的执行过程被挂起,而next方法返回值为yield关键字后面表达式的值,即为1。
当调用gen.send(2)方法时,python首先恢复MyGenerator方法的运行环境。同时,将表达式(yield 1)的返回值定义为send方法参数的值,即为2。这样,接下来value=(yield 1)这一赋值语句会将value的值置为2。继续运行会遇到yield value语句。因此,MyGenerator方法再次被挂起。同时,send方法的返回值为yield关键字后面表达式的值,也即value的值,为2。
当调用send(3)方法时MyGenerator方法的运行环境。同时,将表达式(yield value)的返回值定义为send方法参数的值,即为3。这样,接下来value=(yield value)这一赋值语句会将value的值置为3。继续运行,MyGenerator方法执行完毕,故而抛出StopIteration异常。
总的来说,send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。但是需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错。例如
上面代码的输出为
当然,下面的代码是可以接受的
因为当send方法的参数为None时,它与next方法完全等价。但是注意,虽然上面的代码可以接受,但是不规范。所以,在调用send方法之前,还是先调用一次next方法为好。
send方法有一个参数,该参数指定的是上一次被挂起的yield语句的返回值。这样说起来比较抽象,看下面的例子。
def MyGenerator(): value = (yield 1) value = (yield value) gen = MyGenerator() print gen.next() print gen.send(2) print gen.send(3)
输出的结果如下
1 2 Traceback (most recent call last): File "test.py", line 18, in <module> print gen.send(3) StopIteration
上面代码的运行过程如下。
当调用gen.next()方法时,python首先会执行MyGenerator方法的yield 1语句。由于是一个yield语句,因此方法的执行过程被挂起,而next方法返回值为yield关键字后面表达式的值,即为1。
当调用gen.send(2)方法时,python首先恢复MyGenerator方法的运行环境。同时,将表达式(yield 1)的返回值定义为send方法参数的值,即为2。这样,接下来value=(yield 1)这一赋值语句会将value的值置为2。继续运行会遇到yield value语句。因此,MyGenerator方法再次被挂起。同时,send方法的返回值为yield关键字后面表达式的值,也即value的值,为2。
当调用send(3)方法时MyGenerator方法的运行环境。同时,将表达式(yield value)的返回值定义为send方法参数的值,即为3。这样,接下来value=(yield value)这一赋值语句会将value的值置为3。继续运行,MyGenerator方法执行完毕,故而抛出StopIteration异常。
总的来说,send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。但是需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错。例如
gen = MyGenerator() print gen.send(2)
上面代码的输出为
Traceback (most recent call last): File "test.py", line 16, in <module> print gen.send(2) TypeError: can't send non-None value to a just-started generator
当然,下面的代码是可以接受的
gen = MyGenerator() print gen.send(None)
因为当send方法的参数为None时,它与next方法完全等价。但是注意,虽然上面的代码可以接受,但是不规范。所以,在调用send方法之前,还是先调用一次next方法为好。
相关文章推荐
- Python特性(九):生成器对象的throw方法
- Python特性(十一):生成器对象的close方法
- Python yield生成器的send方法考察
- Python 3.6 生成器之Send方法
- python特性(七):通过生成器函数构造序列对象的迭代器
- Python的高级特性8:你真的了解类,对象,实例,方法吗
- 生成器对象的send方法
- Python 用file 对象和open方法处理文件的区别
- Python套接字对象(内建)方法
- Python 文件对象的方法
- 原始ajax通过xmlHttpRequest对象的send()方法提交数据--Get方式和Post方式
- C#对象XML序列化(一):序列化方法和常用特性
- C# 3.0新特性之Automatic Properties(自动属性)、Object Initializers(对象初始化器)、Collection Initializers(集合初始化器)和Extension Methods(扩展方法)
- python socket对象内建方法
- 重构-改善既有代码的设计:对象之间移动特性的八种方法(五)
- 重构-改善既有代码的设计:对象之间移动特性的八种方法(五)
- python学习之获取当前时间的方法(可以任意取时间的任何一个对象显示)
- Java编程那些事儿61—面向对象设计方法和面向对象特性(一)
- python对象序列化或持久化的方法《原创》
- 简明 Python 教程 / 面向对象的编程 / 类与对象的方法