python 如何将函数解释为生成器

blu*_*ggy 5 python yield generator

我知道如果函数中存在“yield”语句,它将被视为生成器。但是当函数(生成器)第一次被调用时,python 解释器是如何工作的。我的意思是当代码被解释时,我认为第一个“gen”将绑定到一个函数对象。为什么它在第一次调用时不像普通函数或类那样在 yield 之前执行语句。它如何在yield之前暂停打印函数的执行

>>> def gen():
...    print("In gen")
...    yield 1
...    yield 2
... 
>>> type(gen)
<type 'function'>
>>> a = gen
>>> type(a)
<type 'function'>
>>> 
>>> b = a()
>>> type(b)
<type 'generator'>
>>> b.next()
In gen
1
>>> b.next()
2
>>> 
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 5

当Python解析def语句,它决定如果代码被定义发电机或功能。如果代码包含一个yield表达式,那么它就是一个生成器。所以当生成器函数a被调用时,它返回一个generator object, b

def语句中的代码在b.next()被调用之前不会执行。


考虑这两个函数:

def gen():
     print('In gen')
     yield 1
     yield 2


def func():
     print('In gen')    
Run Code Online (Sandbox Code Playgroud)

虽然genfunc都是函数,但 Python 知道这gen是一个生成器:

In [96]: import inspect

In [101]: inspect.isgeneratorfunction(gen)
Out[101]: True

In [102]: inspect.isgeneratorfunction(func)
Out[102]: False
Run Code Online (Sandbox Code Playgroud)

如果您查看检查模块内部,您会看到

def isgeneratorfunction(object):
    """Return true if the object is a user-defined generator function.

    Generator function objects provides same attributes as functions.

    See help(isfunction) for attributes listing."""
    return bool((isfunction(object) or ismethod(object)) and
                object.func_code.co_flags & CO_GENERATOR)
Run Code Online (Sandbox Code Playgroud)

显然,Python 在执行函数内部的代码之前首先检查了这一点。

  • @kingdeb:虽然`dis.dis(gen)` 没有表明`gen` 是一个生成器函数,但是`gen.func_code.co_flags` 有一个标志表明`gen` 是一个生成器。所以 `def` 语句正在创建一个知道它的生成器的函数对象。这回答了你的问题了吗? (2认同)