Skip to main content
 首页 » 编程设计

python之生成器是否只是使用 __iter__ 和 next 函数创建新对象

2025年05月04日26rubylouvre

我试图自己搜索这个答案,但是噪音太大了。

python 中的生成器只是一个方便的包装器,方便用户创建迭代器对象吗?

定义生成器时:

def test(): 
  x = 0 
  while True: 
    x += 1 
    yield x 

python 是简单地创建一个新对象,添加__iter__ 方法,然后将其余代码放入next 函数吗?

class Test(object): 
 
  def __init__(self): 
    self.x = 0 
 
  def __iter__(self): 
    return self 
 
  def next(self): 
    self.x += 1 
    return self.x 

请您参考如下方法:

没有。像这样:

>>> def test(): 
...    x = 0 
...    while True: 
...       x += 1 
...       yield x 
... 
>>> type(test) 
<type 'function'> 

所以它返回的是一个函数对象。那里的细节变得多毛;短期类(class)是属于函数(test.func_code)的代码对象被test.func_code.co_flags中的标志之一标记为生成器。 .

您可以反汇编 test 的字节码看看它就像任何其他函数一样,除此之外,生成器函数总是包含一个 YIELD_VALUE操作码:

>>> import dis 
>>> dis.dis(test) 
  2           0 LOAD_CONST               1 (0) 
              3 STORE_FAST               0 (x) 
 
  3           6 SETUP_LOOP              25 (to 34) 
        >>    9 LOAD_GLOBAL              0 (True) 
             12 POP_JUMP_IF_FALSE       33 
 
  4          15 LOAD_FAST                0 (x) 
             18 LOAD_CONST               2 (1) 
             21 INPLACE_ADD 
             22 STORE_FAST               0 (x) 
 
  5          25 LOAD_FAST                0 (x) 
             28 YIELD_VALUE 
             29 POP_TOP 
             30 JUMP_ABSOLUTE            9 
        >>   33 POP_BLOCK 
        >>   34 LOAD_CONST               0 (None) 
             37 RETURN_VALUE 

按照您的想法去做,恐怖才刚刚开始 ;-) 如果您考虑如何创建一个对象来模仿这个:

def test(): 
    yield 2 
    yield 3 
    yield 4 

现在您的 next()方法必须携带额外的隐藏状态才能记住哪个 yield接下来。用一些条件将其包装在一些嵌套循环中,并将其“展开”到单个条目中 next()变成了一场噩梦。