我是Python的新手,我正在阅读Python Tricks一书。在关于生成器的章节中,它给出了以下示例(有一些更改(
class BoundedGenerator:
def __init__(self, value, max_times):
self.value = value
self.max_times = max_times
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count < self.max_times:
self.count += 1
yield self.value
之后,我编写一个循环,实例化生成器并打印值:
for x in BoundedGenerator('Hello world', 4):
print(next(x))
为什么我必须在循环内调用next(X)
?
我(认为(我知道__iter__
函数将在循环线定义中调用,并且__next__
将在每次迭代中调用,但我不明白为什么我必须在循环内再次调用下一个。这不是多余的吗? 如果我不调用__next__
函数,我的循环将永远运行。
由于使用了yield
,您的__next__
方法本身就是一个生成器函数。它必须是改用return
的常规函数。
def __next__(self):
if self.count < self.max_times:
self.count += 1
return self.value # return to provide one value on call
raise StopIteration # raise to end iteration
迭代时,python 调用iter.__next__
来接收新值。如果这是一个生成器函数,则调用仅返回生成器。这与任何其他生成器函数的行为相同:
>>> def foo():
... yield 1
...
>>> foo()
<generator object foo at 0x106134ca8>
这需要您在生成器上调用next
才能实际获取值。同样,由于您将BoundedGenerator.__next__
定义为生成器函数,因此每个迭代步骤仅提供一个新的生成器。
使用return
而不是yield
确实返回值,而不是生成所述值的生成器。此外,您应该在完成后raise StopIteration
- 这表示迭代结束。