【yield 详解 协同程序 生成器表达式】

1》 yield

def res ():
for i in range(10):
x = yield i
r = res()
print r.next()
print r.next()
print r.next()

我们来详细的分析下这个程序的执行

r =res() 我们知道 res方法里面有yield关键字 那么这个方法就被认为是一个 generator

那么 yield i 和 x = yield i  的功能上面的区别的就是 x = yield i 可以通过 send 修改表达式的值

yield i 可以理解加了挂起之后的return

而 x = yileld i 这个表达式

则能够挂机的return + 能够在外部修改返回值

def res ():
for i in range(10):
yield i
print '[1]',i
yield i + 1
print '[2]',i r = res()
print r.next()
print r.next()

如果一个方法里面有两个yield 那么实际上是 这个方法会挂起两次 一次next 只能解除一次挂起

def psychologist():
print 'Please tell me your problems'
while 1:
res=(yield 3)
if res is not None:
if res.endswith('?'):
print ("Don't ask you self too much questions")
elif 'good' in res:
print "A that's good .go on "
elif 'bad' in res:
print "Don't be so negative"
else :
print 'res is None' free = psychologist()
print '[0]',free.next()
print '[1]',free.next()
print '[2]',free.send("I feel bad")
print '[3]',free.send("Are you OK?")
print '[4]',free.send("I'm a good boy")

然后我们再来看这个代码 就简答很多了

res = yield 3

这里 执行next 或者send 的返回值都是 3 这个是不变的

而 res的值 会随着send 的变化而变化

这里我们可以吧next 看做 send(None)

第一次执行next() 会挂起在 yeild 哪里 所有 输出会是 : [0] 3

第二次执行 next() 就相当于 send(None)此时res = None 则会输出 :[1]  res is None 3

最终的全部输出

[0] 3
[1] res is None
3
[2] Don't be so negative
3
[3] Don't ask you self too much questions
3
[4] A that's good .go on
3

 然后  和send 相匹配的函数还有两个

throw :允许客户端代码传入要抛出的任何类型 的异常

close:跟throw 类似 但是只会抛出一个特定的异常 GeneratorExit 在这种情况下 生成器必须在抛出GeneratorExit 或Stopteration

可以在外部 让代码内部抛出异常

那么有了这三个特性我们就能通过生成器来编写协程

2》协程

定义:协同程序是可以挂起,恢复,并且有多个进入点的程序

import  multitask

def A1():
for i in range(3):
print 'A1',i
yield i
print 'in A'
def B1():
for i in range(3):
print 'B1',i
yield i
print 'in B' multitask.add(A1())
multitask.add(B1())
multitask.run()

输出

A1 0
B1 0
in A
A1 1
in B
B1 1
in A
A1 2
in B
B1 2
in A
in B

  

multitask这个模块在这里实现了这一模式 一旦执行到yield这个关键字那么久挂起执行另一个函数的代码

我们可以自己写一个类似的程序
def A1():
for i in range(3):
print 'A1',i
yield i
print 'in A'
def B1():
for i in range(3):
print 'B1',i
yield i
print 'in B' import Queue
class my_task():
def __init__(self):
self._queue = Queue.Queue() def add(self,res):
self._queue.put(res) def run(self):
while not self._queue.empty():
for i in xrange(self._queue.qsize()):
try:
gen = self._queue.get()
gen.send(None)
except StopIteration:
pass
else:
self._queue.put(gen) t = my_task()
t.add(A1())
t.add(B1())
t.run()

这段代码比较复杂了

我们来,了解下 queue 是先进先出的

这样就能很好的理解这个代码了

举个例子 小明和小强在玩游戏机 但是只有一个手柄 他们觉得达成协议 玩超级马里奥 然后一人玩一条命 一直到有一方通关

这里的手柄就是队列 ,通过队列实现这一效果

def a1():
for x in range(4):
print x
yield x def a2():
for x in range(4,8):
yield x threads=[]
threads.append(a1())
threads.append(a2()) def run(threads):
while len(threads) != 0 :
for i in threads:
try:
print i.next()
except StopIteration:
pass
else:
threads.append(i) run(threads)

当然我们也可以通过其他方式来实现这一效果

3》生成器表达式

python 里面为了方便写简单的生成器 提供一个方法 类似于列表推导

用(方法 循环 条件)

python-高级编程-02的更多相关文章

  1. python高级编程之列表推导式

    1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...

  2. python高级编程:有用的设计模式3

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...

  3. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

  4. python高级编程:有用的设计模式1

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...

  5. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

  6. python高级编程之选择好名称:完

    由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...

  7. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  8. Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

  9. Python高级编程-Python一切皆对象

    Python高级编程-Python一切皆对象 Python3高级核心技术97讲 笔记 1. Python一切皆对象 1.1 函数和类也是对象,属于Python的一等公民 ""&qu ...

  10. 第三章:Python高级编程-深入类和对象

    第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...

随机推荐

  1. hive中select中DISTINCT的技巧和使用

    hive中select中DISTINCT的技巧和使用 单表的唯一查询用:distinct 多表的唯一查询用:group by 在使用MySQL时,有时需要查询出某个字段不重复的记录,虽然mysql提供 ...

  2. windows服务器安装安全狗时服务名如何填写

    安全狗安装时“服务名”这一栏指的是apache进程的服务名称,即进入“任务管理-服务”里显示的名称. phpstudy等软件搭建的环境需要设置运行模式为“系统服务”后才能看到服务名.

  3. 微信成为HTML5技术流行的最大推手

    很多热点的事件都是厚积薄发,HTML5就是如此.此前iOS和Android系统已经放弃了Flash,这让HTML5有了一个天然的成长基础.而现在手机硬件的提升和HTML5本身的完善,使得基于HTML5 ...

  4. C++STL概览

    本文转自http://www.cnblogs.com/ggjucheng/archive/2012/01/03/2310884.html 引言 C++ STL可以分为标准容器,算法和函数对象,迭代器和 ...

  5. CVE-2014-1767

    [0x00].简介  CVE-2014-1767漏洞是由于Windows的afd.sys驱动在对系统内存的管理操作中,存在着悬垂指针的问题.在特定情况下攻击者可以通过该悬垂指针造成内存的double ...

  6. java基础——冒泡排序

    最近开始准备面试,所以将Java基础复习一遍,又学习了冒泡排序 冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序 ja ...

  7. Tomcat:使用startup.bat启动tomcat遇到报错

    问题:使用startup.bat启动tomcat的时候报错,按照网页上的办法都试了一遍,但是没有解决问题.命令窗口启动tomcat会一闪而过,然后退出. 解决:1 检查环境变量配置是否有问题: CAT ...

  8. Java基础操作面试题:Map集合排序 需要TreeMap 构造方法参数有比较器 输入字符串,统计A、B、C、D、出现次数,由高到低输出字母和出现次数,使用Map集合完成此题

    Map和Collections是同级别的,不能像List排序那样直接用Collections.sort(new Comparator<?>(){ 复写compara方法}); HashMa ...

  9. iOS--获取文件目录的方法

    很多文章都有写这个问题,我只是为了记录一下,免得总翻书... 1.Documents 目录: 你应该将所有的应用程序数据文件写入到这个目录下.这个目录用于存储用户数据或其它应该定期备份的信息. 2.L ...

  10. python @staticmethod和@classmethod

    Python其实有3个方法,即 静态方法 (staticmethod), 类方法 (classmethod)和 实例方法. 如下: def foo(x): print "executing ...