生成器只是一个函数,它返回一个可以在其上调用的对象,这样每次调用它都返回一些值,直到它引发一个StopIteration异常,表示已生成所有值。这样的对象称为迭代器。
>>> def myGen(n):
... yield n
... yield n + 1
...
>>> g = myGen(6)
我从Understanding Generators in Python?
引用了这个以下是我想弄清楚的事情:
哪个是发电机? myGen
或myGen(6)
?
根据上面提到的引用,我认为生成器应该是myGen
。并且myGen(6)
是返回的迭代器对象。但我真的不确定。
当我尝试这个时:
>>> 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',它不可调用。
但是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
这个问题对我来说也很可疑。
答案 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