【问题标题】:where does the yield store value in pythonpython中的yield存储值在哪里
【发布时间】:2018-01-25 03:29:38
【问题描述】:

我了解generator 一次生成一次值,这可以节省大量内存,而不像list 将所有值存储在内存中。

我想知道pythonyield 如何知道在迭代过程中应该返回哪个值而不将所有数据一次存储在内存中?

据我了解,如果我想使用yield打印1 to 100,需要yield需要先知道或存储1 to 100,然后逐点移动返回值?

如果不是,那么yield如何一次返回一次值,而不将所有值存储在内存中?

【问题讨论】:

  • 它在每个yield 处暂停函数,直到该值被某些东西消耗。您可以通过在生成器中添加一些 print 语句来观察它。
  • @SilvioMayolo 是不是和某种数据结构有关?
  • 虽然不能保证生成器的实现,但协程将是一种相对简单的方法,并且肯定可以用于教学目的。

标签: python generator yield


【解决方案1】:

简单地说,yield 会延迟执行,但会记住它停止的位置。但是,更具体地说,当调用yield 时,生成器函数状态中的变量被保存在“冻结”状态。当再次调用yield 时,内置的next 函数将要传输的数据按行发送回。如果没有更多数据要生成(因此引发了StopIteration),则存储在“冻结”状态的生成器数据将被丢弃。

【讨论】:

    【解决方案2】:

    每次生成器yields,生成器的堆栈帧都会保存在生成​​器对象中,所以it can be restored when execution resumes(当请求下一个值时)。

    你可以看到the structure definition on CPython here

    如果你想看更多,生成器有点内省,所以你可以看看,比如说,本地人的进展,它当前所在的行号等:

    def myrange(n):
        for i in range(n):
            yield i
    
    mr = myrange(10)
    
    # Before any values consumed:
    print(mr.gi_frame.f_locals)  # Outputs {'n': 10}
    print(mr.gi_frame.f_lineno)  # Outputs 1
    
    next(mr)  # Advance one
    
    print(mr.gi_frame.f_locals)  # Outputs {'n': 10, 'i': 0}
    print(mr.gi_frame.f_lineno)  # Outputs 3
    
    list(mr)  # Consumes generator
    
    print(mr.gi_frame)  # Outputs None; the frame is discarded when the generator finishes
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-25
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 2018-11-09
      相关资源
      最近更新 更多