函数生成器与Python 3中的类生成器

cha*_*rre 4 python generator python-3.x

为什么函数发生器和类生成器的行为不同?我的意思是,使用类生成器,我可以根据需要多次使用生成器,但是使用函数生成器,我只能使用它一次?为什么这样?

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=' ')
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 6

调用该f_gen()函数会生成一个迭代器(特别是一个生成器迭代器).迭代器只能循环一次.您的类不是迭代器,而是一个可迭代的对象,可以生成任意数量的迭代器.

每次使用时,您的类都会生成一个新的生成器迭代器for,因为在您传入的对象上for应用该iter()函数,而该函数又调用object.__iter__(),在您的实现中,每次调用它时都会返回一个新的生成器迭代器.

换句话说,您可以通过调用iter(instance)instance.__iter__()循环之前使类的行为方式相同:

c_gen = CCounter(5,10)
c_gen_iterator = iter(c_gen)
for i in c_gen_iterator:
    # ...
Run Code Online (Sandbox Code Playgroud)

您也可以使CCounter()迭代通过返回self__iter__,并添加object.__next__()方法(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
Run Code Online (Sandbox Code Playgroud)