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'>'''









本文转自xsster51CTO博客,原文链接http://blog.51cto.com/12945177/1932220: ,如需转载请自行联系原作者





相关文章
|
Java 调度
线程的yield操作
线程的yield操作的作用是让出目前正在执行的线程放弃当前的执行,让出CUP权限,使得CPU去执行其他的线程。处于让步状态的JVM层面的线程状态仍然是RUNNABLE状态,但是该线程所对应的操作系统层面的线程从状态上来说会从执行状态编程就绪状态。线程yield时,线程放弃和重占CPU的时间是不确定的,可能是刚刚放弃CPU,马上又获得CPU执行权限,重新开始执行。
66 0
|
4月前
|
Python
yield关键字
yield关键字
|
4月前
|
算法 Java 调度
深入理解 Thread 类的 Yield 方法
【8月更文挑战第22天】
164 4
|
7月前
|
设计模式 编解码 程序员
探索 C++ 20 (co_await、co_yield 和 co_return)协程基本框架的使用
探索 C++ 20 (co_await、co_yield 和 co_return)协程基本框架的使用
654 2
探索 C++ 20 (co_await、co_yield 和 co_return)协程基本框架的使用
|
7月前
|
JavaScript 容器
generator 和 yield的使用
generator 和 yield的使用
46 0
|
测试技术 数据库连接 数据库
pytest(7)-yield与终结函数
通过上一篇文章,我们已经知道了pytest中,可以使用Fixture来完成运行测试用例之前的一些操作如连接数据库,以及测试执行之后自动去做一些善后工作如清空脏数据、关闭数据库连接等。 我们已经学会了fixture函数的简单用法,但其实fixture还提供了两种非常优雅高效的写法,来完成测试执行前的处理操作与执行后的处理操作,即使用yield或addfinalizer来实现。
pytest(7)-yield与终结函数
|
Java 调度
Java线程方法-执行(join) ,礼让(yield)
Java线程方法-执行(join) ,礼让(yield)
133 0
|
C# 索引
C#中的yield
C#中的yield
110 0
|
监控 调度
线程方法:sleep( )、wait()、join( )、yield( )的区别
线程方法:sleep( )、wait()、join( )、yield( )的区别
418 0
|
存储 开发框架 .NET
关于C# yield 你会使用吗?
假设有这样一个需求:在一个数据源(下面代码arry)中把其中大于4的数据取出来遍历到前台,怎么做?(不使用linq)
202 0