python yield 实例理解要点
2015-08-19 23:45
676 查看
结合下面代码为例理解:
1、函数对象包含yield语句后,yield_in_loop变成了generatorfunction,成了generatorType对象的构造器
2、yield_in_loop() 每次调用产生一个iterable可迭代的generator,对象实例互不影响
3、每次generator的实例执行next()才开始执行yield语句生成迭代结果(yield后可以为逗号分开的多个对象)并在该语句后立即中断待命,(如有下个yield语句可执行,下次执行则从紧随yield的下一个语句执行至下下个yield语句中断......)
4、send(arg)给generator的arg替换当前yield的迭代结果【首次迭代send(None)=next(),首次参数必须为None,因为还没有开始执行的yield表达式,就没有地方可以send值】
5、send(arg)的返回值就就是传递给下一个yield表达式的值,也即send(arg)的返回值来自下一个yield表达式的值,而不是来自接受send(arg)传递值的yield表达式,“回音壁”!
1、函数对象包含yield语句后,yield_in_loop变成了generatorfunction,成了generatorType对象的构造器
2、yield_in_loop() 每次调用产生一个iterable可迭代的generator,对象实例互不影响
3、每次generator的实例执行next()才开始执行yield语句生成迭代结果(yield后可以为逗号分开的多个对象)并在该语句后立即中断待命,(如有下个yield语句可执行,下次执行则从紧随yield的下一个语句执行至下下个yield语句中断......)
4、send(arg)给generator的arg替换当前yield的迭代结果【首次迭代send(None)=next(),首次参数必须为None,因为还没有开始执行的yield表达式,就没有地方可以send值】
5、send(arg)的返回值就就是传递给下一个yield表达式的值,也即send(arg)的返回值来自下一个yield表达式的值,而不是来自接受send(arg)传递值的yield表达式,“回音壁”!
# -*- coding: utf-8 -*- ''' Created on 2015年8月17日 @author: laughlast ''' from inspect import isgeneratorfunction from collections import Iterable import unittest import types def yield_in_loop(): sendlist = [] for i in range(1, 4): # yield可产生多个值 y = yield i, sendlist sendlist.append(y) print '#', i, y, sendlist class Test(unittest.TestCase): def test1_next_yield(self): '''test1_next_yield''' y1 = yield_in_loop() self.assertIsInstance(yield_in_loop(), types.GeneratorType, \ 'yield_in_loop():是生成器类型') self.assertIsInstance(yield_in_loop(), Iterable, \ 'yield_in_loop():是迭代器类型') self.assertTrue(isgeneratorfunction(yield_in_loop), \ 'yield_in_loop:是生成器函数类型,不是生成器') self.assertFalse(isinstance(yield_in_loop, (Iterable, types.GeneratorType)), \ 'yield_in_loop:不是生成器、迭代类型') self.assertEqual(y1.next()[0], 1, '当为 1') y = y1.next() self.assertEqual(y[0], 2, '当为 2') self.assertIsInstance(y, types.TupleType, \ 'yield语句后面传回多个参数,生成的值为tuple系列类型') # 迭代器特性,y为元组Tuple解包 i, sendlist = y1.next() self.assertEqual(i, 3, '当为 3') self.assertTrue(sendlist == [None, None], 'next()无值传递') with self.assertRaises(StopIteration): # 'StopIteration:“迭”停' y1.next() self.fail('来错地方了') def test2_send_yield(self): '''test2_send_yield''' y1 = yield_in_loop() with self.assertRaises(TypeError): self.assertEqual(y1.send('Not None'), 1, \ 'TypeError:首次只能send(None)') self.assertEqual(y1.send(None)[0], 1, '当为 1') self.assertEqual(y1.send(88)[0], 2, '当为 2') # i为被替换的yield本身正常迭代结果,sendlist保存的是send(99)替换后的yield迭代结果 i, sendlist = y1.send(99) self.assertEqual(i, 3, '当为 3') self.assertTrue(sendlist == [88, 99], '当为[88, 99]') with self.assertRaises(StopIteration): # 'StopIteration:“迭”停' i, sendlist = y1.send(100) self.fail('来错地方了') # send(100):100替换掉当前yield的迭代值3(上面处理generator产生的异常StopIteration) self.assertTrue(sendlist == [88, 99, 100], '当为[88, 99,100]') if __name__ == "__main__": unittest.main() #测试输出 # 1 None [None]. # 2 None [None, None] # 3 None [None, None, None] # 1 88 [88] # 2 99 [88, 99] # 3 100 [88, 99, 100] . ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
相关文章推荐
- Python & OpenCV混合编程
- Python 中 logging 日志模块在多进程环境下的使用
- python集成开发eclipse环境安装
- 使用 Python 为 KVM 编写脚本,第 1 部分: libvirt
- Ubuntu下python3 安装 pip 和 Django
- 通过python-libvirt管理KVM虚拟机-2
- Python3 之 import 和 当前目录
- python 单步调式
- Python中异常(Exception)的总结
- [转]使用 Vagrant 打造跨平台开发环境
- Python环境的搭建
- Python随机数生成方法
- python科学计算_scipy_常数与优化
- python Shabang 标记
- Python学习笔记二:Python中的列表
- [Python爬虫] 在Windows下安装PIP+Phantomjs+Selenium
- Python中的“_"
- python常用的十进制、16进制、字符串、字节串之间的转换(长期更新帖)
- 活学活用wxPython -> 给你的wxPython程序一个稳固的基础
- python接口的定义