我试图自己搜索这个答案,但声音太大了。
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
答案 0 :(得分:2)
否 - 生成器还提供其他方法(.send
,.throw
等),并且可以用于更多目的,而不仅仅是创建迭代器(例如协同程序)。
确实,generators
是完全不同的野兽和核心语言特征。如果他们没有融入语言,那么在香草蟒蛇中创建一个非常难(可能是不可能的)。
据说,生成器的一个应用程序是为创建迭代器提供一种简单的语法: - )。
答案 1 :(得分:2)
不。像这样:
>>> def test():
... x = 0
... while True:
... x += 1
... yield x
...
>>> type(test)
<type 'function'>
它返回的是一个函数对象。那里的细节变得毛茸茸;简短的过程是属于函数(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
。用一些条件包装在一些嵌套循环中,然后&#34;展开&#34;它成为单一条目next()
成为一场噩梦。
答案 2 :(得分:1)
python中的生成器只是一个方便的包装器,供用户创建迭代器对象吗?
没有。 generator
是一个函数,其中iterators
是类。因此,生成器不能是迭代器的对象。但在某种程度上,你可以说生成器是一种简化的方法来获得像功能一样的迭代器。这意味着:
所有生成器都是迭代器,但并非所有迭代器都是生成器。
我强烈建议您参考下面的wiki链接:
迭代器通常是具有next
方法的东西,用于从流中获取下一个元素。生成器是一个与函数绑定的迭代器。
我建议你参考:Difference between Python's Generators and Iterators。