我有以下示例,其中类的下一个方法应该从两个生成器返回值:
class Test():
def __next__(self):
g1, g2 = self._gen1(), self._gen2()
return next(g1), next(g2)
def _gen1(self):
i = 0
while True:
yield i
i += 2
def _gen2(self):
i = 1
while True:
yield i
i += 2
但是,当我为此类调用next
时,值不会递增。
>>> t = Test()
>>> next(t)
>>> (0, 1)
>>> next(t)
>>> (0, 1)
有什么问题?有没有更有说服力的方式来写这门课程?
答案 0 :(得分:1)
虽然我不知道你想要完成什么,但这是一个清理版本(我认为)可以做你想要的。
class Test():
def __init__(self):
self.g1 = self._gen2()
self.g2 = self._gen1()
def __next__(self):
return next(self.g1), next(self.g2)
def _gen1(self):
i = 0
while True:
yield i
i += 2
def _gen2(self):
i = 1
while True:
yield i
i += 2
t = Test()
print(next(t))
print(next(t))
print(next(t))
答案 1 :(得分:0)
您的代码无法正常工作,因为它会在每个时间__next__()
重新创建生成器函数,这会在下一个next()
值之前将它们有效地重置为初始状态退回:
def __next__(self):
g1, g2 = self._gen1(), self._gen2() # Don't do this here.
return next(g1), next(g2)
您可以通过添加__init__()
方法并在其中初始化它来解决此问题:
class Test:
def __init__(self):
self.g1, self.g2 = self._gen1(), self._gen2() # Initialize here.
def __next__(self):
return next(self.g1), next(self.g2)
...
一个更有说服力,更简洁的方法来做同样可以避免问题的方法是使用内置zip()
function创建一个“生成器迭代器”,它将从每个生成器返回每个生成器的下一个值对时间被称为。另一个优点是只需更改__init__()
方法即可轻松扩展以处理更多生成器。
这就是我的意思:
class Test:
def __init__(self):
self.generators = zip(self._gen1(), self._gen2())
def __next__(self):
return next(self.generators)
def _gen1(self):
i = 0
while True:
yield i
i += 2
def _gen2(self):
i = 1
while True:
yield i
i += 2
t = Test()
for _ in range(3):
print(next(t))
输出:
(0, 1)
(2, 3)
(4, 5)