【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. ubuntu和window之间如何共享文件

    参考网上的自己动手实现共享文件: 1.打开虚拟机进入ubuntu系统,先安装增强功能包 2.安装完重启虚拟机后,在window下创建一个专门用来共享的文件夹 3.切换到ubuntu系统,在设备的共享文 ...

  2. React日常注意点

    1.在定义组件的时候,名字首字母一定要大写 最近刚学,我会持续把自己学习过程中的的注意点在这里逐个列出,敬请等待!

  3. 如何在Android Studio中导入JNI生成的.so库

    由于在原来的ADT的Eclipse环境中,用ndk_build工具生成了相应的各个.so库文件之后,eclipse工具就会自动把这些库导入到apk中.而Android Studio目前为止(0.86版 ...

  4. 常用css和js组件

    1 . input框中插入图标 <div class="col-sm-12 col-xs-12 setLineHeight"> <div class=" ...

  5. Python3+Selenium3+webdriver学习笔记11(cookie处理)

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记11(cookie处理)'''from selenium im ...

  6. webpack安装包的时候 1程序目录不要在C盘 2路径不要有中文 3用cnpm

    webpack安装包的时候 1程序目录不要在C盘 2路径不要有中文 3用cnpm

  7. An Intuitive Explanation of Convolutional Neural Networks

    https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/ An Intuitive Explanation of Convolu ...

  8. 【dp】守望者的逃离

    妙 题目描述 恶魔猎手尤迪安野心勃勃,他背着了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快 ...

  9. JQ之$.ajax()方法以及ajax跨域请求

    AJAX(Asynchronous javascript AND xml :异步javascript和xml):是一种创建交互式网页应用的网页开发技术.AJAX可以在不重新加载整个页面的情况下与服务器 ...

  10. Linux基础学习-crond系统计划任务

    系统计划任务 大部分系统管理工作都是通过定期自动执行某个脚本来完成的,那么如何定期执行某个脚本,从而实现运维的自动化,这就要借助Linux的cron功能了. 计划任务分为一次性计划任务和周期性计划任务 ...