yield 的理解

最近在学习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 nfor i in xrange(5):    print(i)

结果:

‘‘‘4
3
2
1
0‘‘‘

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

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

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

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

import randomdef producer():    while True:
        data=random.randint(0,9)        print(‘生产了:‘,data)        yield datadef 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‘>‘‘‘
时间: 2024-10-25 01:49:20

yield 的理解的相关文章

yield个人理解及简明示例

1.写法有2种:yield return <expression>和yield breakyield用于在迭代中返回一个值,并将值带入下一次迭代中.yield break则意味着停止迭代.纯粹的文字描述,一千个人有一千个说法,还是用代码更容易说清楚.2.官方示例(略带修改): private void button1_Click(object sender, EventArgs e) { string s = string.Empty; foreach (int i in List.Power

对yield 的理解

最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结. yield 是一个类似于 return的语法,但是对于return 而言,在其执行之后,意味着将数据返回给调用者,子程序结束,但是yield却不一样,它能够继续执行,直到下一个yield 转交执行权,之后又可以进入继续执行,周而复始,直到抛出异常. for in range()是一个简单有用的循环,之前的学习知道range()返回的是一个对象,有惰性求值的特

C#中yield关键字理解

yield关键字之前用得较少,但是在做项目开发的过程中也遇到了,当时有点迷惑,就顺便研究学习了一下,以下是个人理解,不到之处欢迎拍砖!废话就到这,上代码: class Program { static void Main(string[] args) { string[] strs = new string[] { "1", "2", "3", "4" }; foreach (var item in GetInts(strs)

python中generator;对yield的理解

最近学到python的协程的时候,对于yield就是没理解清楚,后来查到资料之后明白了,定义函数里面有yield语句则就是g=callable()就成为了一个generator,其实yield就类似于return语句,暂停执行并返回值,当generator调用这个值之后,它就没有这个值了,具体可以参考https://blog.csdn.net/mieleizhi0522/article/details/82142856 原文地址:https://www.cnblogs.com/pason-blo

对线程中断,join,yield的理解

一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果. 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了 那么不能直接把一个线程搞挂掉, 但有时候又有必要让一个线程死掉, 或者让它结束某种等待的状态 该怎么办呢? 优雅的方法就是, 给那个线程一个中断信号, 让它自己决定该怎么办. 比如说, 在某个子线程中为了等待一些特定条件的到来, 你调用了Thread.sleep(10000), 预期线程睡10秒之后自己醒

python 之yield个人理解

!/usr/bin/python3 #-*- coding:utf-8 -*- def a(max):     n = 0     while n < max:         c = ['aa','bb','cc','dd','rr','ff']         print  'yield 前面',n         yield c[n]         print 'yield 后面',n         n+=1 for i in a(6):     print "for循环prin

【并发】1、关于线程的几种状态&amp;关于yield的理解

最近在看disruptor源码,在获取ringbuffer的下一个序列的时候,disruptor有几种等待策略,其中有YieldingWaitStrategy类,是使用java的Thread.yield();方法作为等待的方式,了解了一下 Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态 那么线程的这几种状态是什么呢,今天系统总结一下 我们翻开thread类的源码可以看到有一个State的枚举类型 其中有以下几种分别代表: NEW  线程尚未启动的线程状态. RUNNABLE  可

关于Python中的yield的理解

生成器:yield表达式构成的函数就是生成器:每一个生成器都是一个迭代器(但是迭代器不一定是生成器).return就是迭代器: yield的功能类似于return,不同之处在于它返回的是生成器. 什么是生成器,你可以通俗的认为,在一个函数中,使用了yield来代替return的位置的函数,就是生成器. 它不同于函数的使用方法是:函数使用return来进行返回值,每调用一次,返回一个新加工好的数据返回给你:yield不同,它会在调用生成器的时候,把数据生成object,然后当你需要用的时候,要用n

php yield

php中关于 yield 关键字的介绍[点击查看] <?php function gen_one_to_three() { for ($i = 1; $i <= 3; $i++) { //注意变量$i的值在不同的yield之间是保持传递的. yield $i; } } 官方上的例子, 可以理解为, 调用 yield $i 时, yield 向生成器返回 $i 的值, 官方上的输出也是容易理解的, 如果稍作修改: <?php function gen_one_to_three() { fo