最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结。

  yield 是一个类似于 return的语法,但是对于return 而言,在其执行之后,意味着将数据返回给调用者,子程序结束,但是yield却不一样,它能够继续执行,直到下一个yield 转交执行权,之后又可以进入继续执行,周而复始,直到抛出异常。

  for in range()是一个简单有用的循环,之前的学习知道range()返回的是一个对象,有惰性求值的特点,下面是一个利用yield简单模拟range()函数的特点

def xrange(m):
n=m
while(n):
n-=1
yield n
for i in xrange(5):
print(i)

结果:

'''
4
3
2
1
0
'''

这种独特语法现象的原因,从书中摘出相关资料如下:

  当函数中使用yield产生一个值的时候,调用函数会返回一个generator对象,也就是一个生成器,此对象有__next__()方法,通常会调用next()调用该方法取出下一个产生的值,若无法产生下一个值,就会发生StopIteration这样的异常  --《Python程序设计教程》

除了解释以上现象,反之也可推测 for in 函数的参数可以是生成器,生成器具有惰性求值特点,推测之前遇到过惰性求值的都是生成器(推测)

yield可以通过send函数来产生值,下面用一个课本上的DEMO来熟悉其相关函数的使用,课本完成了一个生产者消费者模型:

import random
def producer():
while True:
data=random.randint(0,9)
print('生产了:',data)
yield data
def consumer():
while True:
data=yield
print('消费了:',data)
def clerk(jobs,producer,consumer):
print('执行了{}次生产与消费'.format(jobs))
p=producer()
c=consumer()
next(c) #这里容易出错
for i in range(jobs):
data=next(p)
c.send(data)
clerk(5,producer,consumer)

上面注释的地方比较有意思,只是执行一次yield,而没有任何输出,似乎是没用,但是删除之后程序却无法执行,我的理解是必须执行一次使值转化成生成器对象才能接受相关数据。

为了印证我的观点,执行以下代码:

print(type(producer))
print(type(producer()))

输出:

'''
<class 'function'>
<class 'generator'> '''

对yield 的理解的更多相关文章

  1. yield的理解

    yield的理解:yield命令是异步两个阶段的分界线需要先对迭代器和生成器进行理解: 迭代器:是一种支持next()操作的对象.它包含一组元素,当执行next()时,返回其中一个元素:当所有元素都被 ...

  2. yield个人理解及简明示例

    1.写法有2种:yield return <expression>和yield breakyield用于在迭代中返回一个值,并将值带入下一次迭代中.yield break则意味着停止迭代. ...

  3. 转载yield关键字理解

    实现IEnumerable接口及理解yield关键字   [摘要]本文介绍实现IEnumerable接口及理解yield关键字,并讨论IEnumerable接口如何使得foreach语句可以使用. 本 ...

  4. C#中yield关键字理解

    yield关键字之前用得较少,但是在做项目开发的过程中也遇到了,当时有点迷惑,就顺便研究学习了一下,以下是个人理解,不到之处欢迎拍砖!废话就到这,上代码: class Program { static ...

  5. 迭代器,生成器,yield,yield from理解

    迭代器 说到迭代器就得想说可迭代对象Iterable,实现了__iter__()方法的对象都是可迭代对象,例如很多容器,list ,set, tuples.使用iter方法可以把一个可迭代对象变成迭代 ...

  6. Python yield函数理解

    Python中的yield函数的作用就相当于一个挂起,是不被写入内存的,相当于一个挂起的状态,用的时候迭代,不用的时候就是一个挂起状态,挂起状态会以生成器的状态表现

  7. Python中yield深入理解

    众所周知,python中的yield有这样的用法: def test(alist): for i in alist: yield i 这样,这个test函数就变成了一个生成器,当每次调用的时候,就会自 ...

  8. Thread.yield( )通俗理解

    一. Thread.yield( )方法: 使当前线程从执行状态(运行状态)变为可执行态(就绪状态).cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不 ...

  9. Unity3D协程yield的理解

    Unity3D的协程概括地将就是:对于一段程序,你可以加上yield标明哪里需要暂停,然后在下一帧或者一段时间后,系统会继续执行这段代码.协程的作用:①延迟一段时间执行代码.②等某个操作完成之后再执行 ...

随机推荐

  1. CSS 预处理器中的循环

    本文由 nzbin 翻译,黄利民 校稿.未经许可,禁止转载! 英文出处:css-tricks.com 发表地址:http://web.jobbole.com/91016/ 如果你看过老的科幻电影,你一 ...

  2. yii2 创建ActiveForm(表单)

    表单的生成表单中的方法    ActiveForm::begin()方法    ActiveForm::end()方法    getClientOptions()方法    其它方法:errorSum ...

  3. bigdecimal更精确的浮点处理方式

    Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位内有效数,超过16位,double可能会出现内存 ...

  4. SysTick定时器

    SysTick是一个24位的倒计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值.只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息.下边小结了SysTick的相关寄 ...

  5. 光场相机重聚焦之三——Matlab光场工具包使用、重聚焦及多视角效果展示

    这一小节说一下Matlab光场工具包的使用,展示重聚焦和多视角的效果. 从Lytro illum中导出的raw数据为.lfp格式的光场图像文件(约52M大小),该文件包含以下几部分:光场图像数据raw ...

  6. Java 中字两个字符串判断是否相等(转载)

    java中判断字符串是否相等有两种方法:1.用"=="运算符,该运算符表示指向字符串的引用是否相同,比如: String a="abc";String b=&q ...

  7. Mac 下载安装MySQL

    step 1. 从官网上下载MySQL Community Server step 2. 安装MySQL step 3. 配置mysql和mysqladmin的alias $ vim ~/.bashr ...

  8. linux基础 作业篇

    1.自动部署反向代理 web nfs #!/usr/bin/python #-*- coding:utf-8 -*- #开发脚本自动部署及监控 #1.编写脚本自动部署反向代理.web.nfs: #!/ ...

  9. grunt轻松入门

    项目目录,js源文件 gruntest Gruntfile.js package.json -- js ext community_plugin.js glogin_frm_cover.js iLog ...

  10. #pragma mark指令的作用

    概述: 可以简单地给代码进行一个分组,方便代码的查找(可以不用记,无所谓的小东西) 例如: #pragma mark dog类的声明 @interface Dog :NSObject @end @im ...