问题 发电机是否可以调用?哪个是发电机?


生成器只是一个函数,它返回一个可以在其上调用的对象,这样每次调用它都会返回一些值,直到它引发一个StopIteration异常,表示已生成所有值。这样的对象称为迭代器。

>>> def myGen(n):
...     yield n
...     yield n + 1
... 
>>> g = myGen(6)

我引用了这个 了解Python中的生成器?

这是我想弄清楚的:

  1. 哪个是发电机? myGen 要么 myGen(6)

    根据上面提到的报价,我认为发电机应该是 myGen。和 myGen(6) 是返回的迭代器对象。但我真的不确定。

  2. 当我尝试这个:

    >>> type(myGen)
    <type 'function'>
    >>> type(g)         # <1>this is confusing me.
    <type 'generator'>  
    >>> callable(g)     # <2> g is not callable.  
    False               
    >>> callable(myGen)
    True
    >>> g is iter(g)    # <3> so g should an iterable and an iterator 
    True                # at the same time. And it will be passed as an argument
    >>> for i in g:     # to built-in function `next()` in a "for...in..." loop.
            print i     # (is that correct?)
    
    6
    7     
    

所以,根据 <1> 和 <2>g的类型是'generator',它不可调用。 但 生成器是可调用的,调用生成器会获得一个迭代器对象 这里发生了什么?

当我在寻找答案时,我遇到了 每次定义函数时,python都会创建一个可调用对象。

那么,我可以这样说吗? 当功能 myGen 被定义为, myGen 是一个引用可调用对象的名称,该对象是具有a的类的实例 __call__ 方法。 在这种情况下, myGen 是一个发电机,和 myGen(6) 是什么时候返回的迭代器 myGen 叫做。

但为什么呢 type(g) 返回 <type 'generator'> 在所有? 这回来了 iterator 事情看起来也很可疑,因为没有 return 函数中的语句。

不是吗 函数总是返回一些东西(至少 None,在执行期间没有达到return语句并且到达函数结束时)


13109
2018-02-24 08:07


起源

+1写得好。 - aIKid
我相信生成器是一个创建对象的函数。该对象是生成器,这个生成器是可迭代的。但是你可以调用生成可交换的函数,你可以迭代它。 - Trimax


答案:


不幸的是,术语令人困惑,因为“生成器”通常用于指代函数或返回的迭代器,很难说一个用法更正确。该 收益率陈述的文件 说

yield语句仅在定义a时使用 发电机功能,   并且仅用于发电机功能的主体。使用产量   函数定义中的语句足以导致这种情况   定义创建生成器函数而不是正常   功能。

当调用生成器函数时,它返回一个称为a的迭代器    发生器迭代器或者更常见的是,a 发电机

原始PEP介绍了这个概念 说

请注意,当意图从上下文中清除时,不合格的名称   “发电机”可用于指代 无论是发电机功能还是发电机功能   生成器 - 迭代

如果要明确区分,请对函数使用“generator function”,对迭代器使用“generator iterator”。


11
2018-02-24 08:30





1) myGen 是函数,当被调用时返回一个生成器对象 - 所以是的, myGen(6) 是一个生成器对象。

2)发电机供应 __iter__ 和 next()文档


1
2018-02-24 08:13



嗯..我仍然有点困惑为什么亚历克斯说发电机是可以调用的。任何解释? - aIKid