为什么函数生成器和类生成器的行为不同?我的意思是,使用类生成器我可以根据需要多次使用生成器,但是使用函数生成器,我只能使用它一次?为什么这样?
def f_counter(low,high):
counter=low
while counter<=high:
yield counter
counter+=1
class CCounter(object):
def __init__(self, low, high):
self.low = low
self.high = high
def __iter__(self):
counter = self.low
while self.high >= counter:
yield counter
counter += 1
f_gen=f_counter(5,10)
for i in f_gen:
print(i,end=' ')
print('\n')
for j in f_gen:
print(j,end=' ') #no output
print('\n')
c_gen=CCounter(5,10)
for i in c_gen:
print(i,end=' ')
print('\n')
for j in c_gen:
print(j,end=' ')
答案 0 :(得分:5)
调用f_gen()
函数会产生iterator(具体而言,是generator iterator)。迭代器只能循环一次。你的类是不是一个迭代器,而是一个iterable,一个可以生成任意数量的迭代器的对象。
每次使用for
时,您的类都会生成一个 new 生成器迭代器,因为for
会在您传入的对象上应用iter()
function调用object.__iter__()
,在您的实现中,每次调用它时都会返回 new 生成器迭代器。
换句话说,您可以在循环之前调用iter(instance)
或instance.__iter__()
来使该行的行为相同:
c_gen = CCounter(5,10)
c_gen_iterator = iter(c_gen)
for i in c_gen_iterator:
# ...
您还可以从CCounter()
返回self
并添加object.__next__()
method(__iter__
,将object.next()
转换为迭代器在Python 2):
class CCounter(object):
def __init__(self, low, high):
self.low = low
self.high = high
def __iter__(self):
return self
def __next__(self):
result = self.low
if result >= self.high:
raise StopIteration()
self.low += 1
return result
答案 1 :(得分:2)
您的类是可迭代的,但不是迭代器本身。每次在其上调用iter
时,都会得到一个新的迭代器。
如果你想用类复制生成器函数的行为,那么你想要一个像这样的迭代器:
class CCounter(object):
def __init__(self, low, high):
self.low = low
self.high = high
self.counter = self.low
def __iter__(self):
return self
def __next__(self):
if self.counter > self.high:
raise StopIteration()
val = self.counter
self.counter += 1
return val