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

时间:2014-02-24 08:07:20

标签: python generator callable

  

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

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

我从Understanding Generators in Python?

引用了这个

以下是我想弄清楚的事情:

  1. 哪个是发电机? myGenmyGen(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     
    
  3. 因此,根据<1><2>g的类型是'generator',它不可调用。 但是generators are callable, and calling a generator gets you an iterator object 这是怎么回事?

    当我在寻找答案时,我遇到了Every time you define a function python creates a callable object.

    那么,我可以这样说吗? 定义函数myGen时,myGen是一个引用可调用对象的名称,该对象是具有__call__方法的类的实例。 在这种情况下,myGen是一个生成器,myGen(6)是调用myGen时返回的迭代器。

    但为什么type(g)会归还<type 'generator'>? 由于函数中没有iterator语句,因此返回return这个问题对我来说也很可疑。

    不是Functions always return something (at least None, when no return-statement was reached during execution and the end of the function is reached)吗?

2 个答案:

答案 0 :(得分:12)

术语遗憾的是令人困惑,因为“生成器”通常用于指代函数或返回的迭代器,很难说一个用法更正确。 documentation of the yield statement

  

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

     

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

original PEP introducing the concept

  

注意,当意图从上下文中清除时,不合格的名称   “generator”可用于将引用到生成器函数或a   生成器 - 迭代

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

答案 1 :(得分:1)

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

2)生成器提供__iter__next()docs