我正在学习Python,并且试图弄清楚为什么自定义类中包含'yield'语句的函数无法按预期运行。我的目标是使功能充当生成器;也就是说,它返回一个生成器迭代器,然后可以在for语句中使用它。
该类的定义如下:
class inclusive_range:
def __init__(self, num):
self._start = 0
self._step = 1
self._stop = num
self._next = self._start
# iterator implementation - would like to avoid this
# def __iter__(self):
# return self
#
# def __next__(self):
# if self._next > self._stop:
# raise StopIteration
# else:
# _r = self._next
# self._next += self._step
# return _r
# generator implementation - trying to get this to work
def generator(self):
if self._next < self._stop:
_r = self._next
self._next += self._step
yield _r
在主程序中运行以下语句时,迭代器实现(注释掉)可以按预期工作:
for i in inclusive_range(10):
print(i)
期望输出的位置(打印数字0到10)。
但是,当我尝试按以下方式使用生成器时:
for i in inclusive_range(10).generator():
print(i)
输出仅为单个数字0。起初我以为generator()调用未按预期返回迭代器,所以我使用调试器进行了研究:
n = inclusive_range(10)
# I pulled up the "evaluate expression" window in the debugger and did the following:
n.generator().__next()__ # prints 0
n.generator().__next()__ # prints 1!
n.generator().__next()__ # prints 2!
n.generator().__next()__ # prints 3!
# ...and so on until StopIteration is raised.
所以我的问题是...它看起来像调试器中预期的那样工作,为什么它只返回第一个值?
答案 0 :(得分:1)
我认为您希望在生成器方法中使用while
循环而不是if
语句:
# generator implementation - trying to get this to work
def generator(self):
while self._next <= self._stop:
_r = self._next
self._next += self._step
yield _r
答案 1 :(得分:1)
问题源于发生器的结构不正确。您将需要一个循环,其中yield
是所需的值,同时更新对象状态以准备yield
下一个值。简而言之,您只需要在if
中将while
替换为generator(self)
,就可以了!这段代码对我有用(注释中为清楚起见删除了代码):
class inclusive_range:
def __init__(self, num):
self._start = 0
self._step = 1
self._stop = num
self._next = self._start
# generator implementation - trying to get this to work
def generator(self):
while self._next < self._stop: # <-- while instead of if
_r = self._next
self._next += self._step
yield _r
测试:
> for i in inclusive_range(10).generator():
print(i)
0
1
2
3
4
5
6
7
8
9
快乐编码!