python-高级编程-02
【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的更多相关文章
- python高级编程之列表推导式
1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...
- python高级编程:有用的设计模式3
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...
- python高级编程:有用的设计模式2
# -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...
- python高级编程:有用的设计模式1
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...
- python高级编程技巧
由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr ...
- python高级编程之选择好名称:完
由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍
原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...
- Python高级编程-Python一切皆对象
Python高级编程-Python一切皆对象 Python3高级核心技术97讲 笔记 1. Python一切皆对象 1.1 函数和类也是对象,属于Python的一等公民 ""&qu ...
- 第三章:Python高级编程-深入类和对象
第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...
随机推荐
- BandwagonHost 5个数据中心/机房Ping速度测试亲自体验
我们选择Bandwagonhost服务器的原因之一在于有5个数据中心,而且与众多其他VPS不同之处在于可以自己后台切换机房和IP,这样我们 在遇到不满意的速度时候,可以自己切换其他机房更换,而且对于有 ...
- uva806 Spatial Structures 空间结构 (黑白图像的四分树表示)
input 8 00000000 00000000 00001111 00001111 00011111 00111111 00111100 00111000 -8 9 14 17 22 23 44 ...
- 简易数据分析 02 | Web Scraper 的下载与安装
这是简易数据分析系列的第 2 篇文章. 上篇说了数据分析在生活中的重要性,从这篇开始,我们就要进入分析的实战内容了.数据分析数据分析,没有数据怎么分析?所以我们首先要学会采集数据. 我调研了很多采集数 ...
- 01_1JAVA简介
01_1JAVA简介 1. Java基础 语法基础.OO.Exception.Array.基础类.I/O Stream.Collection /Generic.Thread.TCP/UDP.GUI.M ...
- ARC中__weak;__strong;__unsafe_unretained;修饰词
测试代码: // Human.h代码 @interface Human : NSObject @property (nonatomic, weak) Cat *pinkCat; @property ( ...
- attachEvent和addEventListener 的使用方法和区别
attachEvent方法,为某一事件附加其它的处理事件.(不支持Mozilla系列)addEventListener方法 用于 Mozilla系列document.getElementById(&q ...
- cesium底图加载底图切换 基于天地图服务
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue-awesome-swiper插件爬坑
最近自己在做一个基于vue的知乎的移动端单页面,遇到很多坑,先说一下遇到最大的坑,其实并不推荐使用 vue-awesome-swiper,如果项目应用轮播,切换少的话.言归正传,现在来介绍vue-aw ...
- 【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】
还是来致敬一下那过往吧 题目分析 先丢代码 #include<bits/stdc++.h> ; ; ; struct node { int top,son,fa,tot; }a[maxn] ...
- mysql 5.7安装密码校验插件validate_password
在使用服务器插件之前,必须将它们加载到服务器中.MySQL支持在服务器启动和运行时加载插件.还可以在启动时控制加载插件的激活状态,并在运行时卸载它们.在加载插件时,可以从INFORMATION_SCH ...