Python的yield关键字有什么作用?

栏目: Python · 发布时间: 5年前

内容简介:我是从这个时候yield的主要作用应该在于节省内存,例如查询数据库的时候,结果的数量非常 多,此时yield就可以发挥作用,在用到它的时候才产生数据。而不是像list一样保存 所有的数据。

我是从 python 2.7 开始接触的,要说 python 的各种历史,我还真的说不出来。 不过好在有 peps 记录了python的发展和进化。今天我们来挖挖 yield 的 历史。

PEP-255 : 在2001年的时候, yield首次在python中出现。这时候的用法比较简单,只是单纯的作为 generator :

In [1]: def foo():
   ...:     for i in range(10):
   ...:         yield i
   ...:

In [2]: gen = foo()

In [3]: for i in gen:
   ...:     print(i, end=', ')
   ...:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

这个时候yield的主要作用应该在于节省内存,例如查询数据库的时候,结果的数量非常 多,此时yield就可以发挥作用,在用到它的时候才产生数据。而不是像list一样保存 所有的数据。

PEP-380 : 这个pep介绍了新的语法 yield from 。他的作用主要是把对原本的generator产生作用的语句指向另外一个 generator,例如:

In [1]: def foo():
   ...:     for i in range(10):
   ...:         yield i
   ...:

In [2]: def bar():
   ...:     yield from foo()
   ...:

In [3]: gen = bar()

In [4]: for i in gen:
   ...:     print(i, end=', ')
   ...:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

通过 yield from foo() 我们能直接从 bar() 这个generaotor里拿到 foo() 产 生的值。这也是传说中的代理模式的应用。

yield 和 yield from 有区别吗?什么时候该用哪个?

我们分别用一下:

In [1]: def foo():
   ...:     yield [1, 2, 3]
   ...:

In [2]: def bar():
   ...:     yield from [1, 2, 3]
   ...:

In [3]: for i in foo():
   ...:     print(i)
   ...:
[1, 2, 3]

In [4]: for i in bar():
   ...:     print(i)
   ...:
1
2
3

可以看出来,如果直接yield那是会直接把整个 [1, 2, 3] 给yield出来。什么时候 用yield什么时候用yield from傻傻分不清怎么办?有一个trick,但是如果你用这个 被主管打了可千万别怪我:

In [1]: class Future:
   ...:     pass
   ...:

In [2]: def foo():
   ...:     yield Future()
   ...:

In [3]: def bar():
   ...:     yield from Future()
   ...:

In [4]: for i in foo():
   ...:     pass
   ...:

In [5]: for i in bar():
   ...:     pass
   ...:
-------------------------------------------------------------------
TypeError                         Traceback (most recent call last)
<ipython-input-5-c0dd2fd4aa2d> in <module>()
----> 1 for i in bar():
      2     pass

<ipython-input-3-1c731241676c> in bar()
      1 def bar():
----> 2     yield from Future()
      3

TypeError: 'Future' object is not iterable

In [6]: class Future:
   ...:     def __iter__(self):
   ...:         yield self
   ...:

In [7]: for i in bar():
   ...:     pass
   ...:

In [8]:

为什么?因为

def foo():
    yield from bar()

几乎相当于

def foo():
    for i in bar():
        yield i

但是不同的是, yield from 会把对 foo() 作用的 next , .send , .throw 全部 传递给 bar() 但是后面一种形式不会,也就是说后面一种形式把代理这个动作几乎丢掉 了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Node.js实战

Node.js实战

[美] Mike Cantelon、[美] TJ Holowaychuk、[美] Nathan Rajlich / 吴海星 / 人民邮电出版社 / 2014-5 / 69.00元

服务器端JavaScript?没错。Node.js是一个JavaScript服务器,支持可伸缩的高性能Web应用。借助异步I/O,这个服务器可以同时做很多事情,能满足聊天、游戏和实时统计等应用的需求。并且既然是JavaScript,那你就可以全栈使用一种语言。 本书向读者展示了如何构建产品级应用,对关键概念的介绍清晰明了,贴近实际的例子,涵盖从安装到部署的各个环节,是一部讲解与实践并重的优秀......一起来看看 《Node.js实战》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试