Python中的“收益”

奥兹古尔

我有一个叫做x的函数,它会生成一个像这样的生成器:

a = 5
def x():
    global a
    if a == 3:
        raise Exception("Stop")
    a = a - 1
    yield a

然后在python shell中,我像这样调用该函数:

>>> print x().next()
>>> 4
>>> print x().next()
>>> 3
>>> print x().next()
>>> <python-input-112-f3c02bba26c8> in x()
          2     global a
          3     if a == 3:
    ----> 4         raise Exception
          5     a = a - 1
          6     yield a

    Exception:

但是,当我调用该函数并将其分配给变量时,其行为会有所不同:

>>> a = 5
>>> b = x()
>>> print b.next()
>>> 4
>>> print b.next()
>>> ----> 1 b.next()
    StopIteration:

这怎么可能呢?它不应该打印出3并在下一次迭代中提高StopIteration吗?

PS:我知道,当我第一次调用该函数时,主体不会运行,只会生成一个generator我不明白的是,如果我调用并将其分配给变量,会发生什么变化?

马丁·彼得斯(Martijn Pieters)

在第一个示例中,您每次都创建一个新的生成器:

x().next()

从顶部开始生成器,因此是第一个语句。a == 3引发异常时,否则生成器仅屈服并暂停

当您稍后分配生成器时,全局a起始于5,然后代码从其离开的位置继续直到它结束或遇到另一条yield语句,然后结束生成器函数结束时,将引发StopIteration

让我们将其分解为以下步骤:

  1. a = 5
  2. 您创建新的生成器并对其进行调用.next()执行以下代码:

    global a
    if a == 3:  # False
        raise Exception("Stop")
    a = a - 1   # a is now 4
    yield a
    

    生成器在最后一行暂停,并4屈服。

  3. 您创建一个新的生成器并对其进行调用.next()a4在开始:

    global a
    if a == 3:  # False
        raise Exception("Stop")
    a = a - 1   # a is now 3
    yield a
    

    生成器在最后一行暂停,并3屈服。

  4. 您创建一个新的生成器并对其进行调用.next()a3在开始:

    global a
    if a == 3:  # True
        raise Exception("Stop")
    

    引发异常。

  5. a = 5再次设定

  6. 您创建一个新的生成器,在其中存储引用b并对其进行调用.next()执行以下代码:

    global a
    if a == 3:  # False
        raise Exception("Stop")
    a = a - 1   # a is now 4
    yield a
    

    生成器在最后一行暂停,并4屈服。

  7. .next() 再次调用由引用的相同的现有生成器b该代码在暂停点处恢复

    该函数此时没有更多代码,然后返回。StopIteration被提出。

如果要使用循环,则可以更好地看到不同之处:

>>> def looping(stop):
...    for i in looping(stop):
...        yield i
...
>>> looping(3).next()
0
>>> looping(3).next()
0

请注意,每次创建新生成器时,循环都是从头开始的。但是,存储参考,您会发现它继续存在:

>>> stored = looping(3)
>>> stored.next()
0
>>> stored.next()
1
>>> stored.next()
2
>>> stored.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

在循环期间,每次yield执行表达式时,代码都会暂停调用.next()将从上次离开的位置继续执行该功能。

StopIteration例外是完全正常的; 生成器传达它们完成的方式。一个for循环查找该异常来结束循环:

>>> for i in looping(3):
...     print i
... 
0
1
2

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Python中的“收益”

来自分类Dev

了解python中的收益

来自分类Dev

集内的收益以消除阵列中的收益

来自分类Dev

集内的收益以消除阵列中的收益

来自分类Dev

R中的排名收益

来自分类Dev

Python异步,期货和收益

来自分类Dev

Python:多处理池中的收益

来自分类Dev

在SQL中运行累积收益

来自分类Dev

如何从收益中获得回报*

来自分类Dev

R中的股票收益比较

来自分类Dev

在contextlib.contextmanager中的收益

来自分类Dev

在SQL中运行累积收益

来自分类Dev

将每日收益转换为r中的每月收益

来自分类Dev

python中是否有一种方法可以更改处理get的收益的顺序?

来自分类Dev

如何在MATLAB(或Python)中模拟根据经验派生的分布的收益?

来自分类Dev

通过使用局部变量而不是全局变量在Python中获得的性能收益的极限?

来自分类Dev

如何在MATLAB(或Python)中模拟根据经验派生的分布的收益?

来自分类Dev

Python 3 asyncio-vs asyncio的收益

来自分类Dev

Python asyncio:收益不被用于未来吗?

来自分类Dev

如何最大化收益-Python

来自分类Dev

单值收益与嵌套的Python列表理解

来自分类Dev

python递归收益以减少内存占用

来自分类Dev

Python asyncio:未来的收益不被使用吗?

来自分类Dev

在Quantmod中调整每日收益

来自分类Dev

从排名最高的商品中获得收益

来自分类Dev

在标量UDF中订阅-意外的收益

来自分类Dev

R中带有NA的累积收益

来自分类Dev

“收益” Node.js中的计算

来自分类Dev

通过R中的ID计算复合收益