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 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...
随机推荐
- Linux系统常用命令大全
一.系统信息操作(备注:红色标记为常用命令,以下类推,不再赘述) arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r ...
- Unity中的各种寻找GameObject方法归纳
1.GameObject.Find():寻找Hierarchy面板中的activie 不为false的游戏对象: 路径如官方事例写法: public class ExampleClass : Mono ...
- Robot Framework(一)入门
1.1简介 Robot Framework是一个基于Python的,可扩展的关键字驱动的测试自动化框架,用于端到端验收测试和验收测试驱动开发(ATDD).它可用于测试分布式异构应用程序,其中验证需要涉 ...
- (六)VMware Harbor简单使用
VMware Harbor简单使用 1. 登陆: [用户:admin , 密码:Harbor12345]配置文件里设置的 登陆后的界面: 2. 用户管理: 2.1 新近用户 3. 仓库管理: 3.1 ...
- 第008课_第1个ARM落版程序及引申
form:第008课_第1个ARM裸板程序及引申 第001节_辅线1_硬件知识_LED原理图 当我们学习C语言的时候,我们会写个Hello程序.那当我们下ARM程序,也该有一个简单的程序引领我们入门, ...
- 设置DdtaGridView控件中网格线的样式
实现效果: 知识运用: DataGridView控件的GridColor属性 //用来获取或设置网格线的颜色 public Color GridColor { get; set; } //属性值: C ...
- 使用notepad++远程编辑Linux文档
上一篇中,我写了如何使用使用ftp服务器实现很方便的通信,这一篇我分享一个使用notepad++的一个NPPFTP插件远程编辑Linux中的文档的小技巧. 首先要确保你的Linux的ftp服务已经打开 ...
- cocos2dx for iOS fmod的音效引擎接入
上一个博客我写了一篇fmod的android接入过程,这一次介绍一下ios接入fmod的方法. 首先下载fmod的api包,解压后,在FMOD Programmers API/api文件夹下有lowl ...
- TabControl重写,添加关闭按钮
class userTabControl : TabControl { const int CLOSE_SIZE = 15; protected override void OnInvalidated ...
- Linux常用命令-----------------磁盘挂载命令
磁盘挂载: [root@sdw1 ~]# mkfs.ext4 /dev/vdb[root@sdw1 ~]# blkid /dev/vdb >> /etc/fstabvi /etc/fsta ...