首页 > 解决方案 > 如何将生成器函数转换为python中的迭代器对象?

问题描述

通常生成器函数比迭代器更容易编写,例如考虑这个示例生成器函数

def generator_fn():
    x = 0
    for y in range(10):
         x += y
         yield x

有没有一种直接的方法可以将任意生成器函数转换为迭代器对象,即

class IteratorFromGenerator(object):

    def __init__(self, generator_fn):
        self.generator_fn = generator_fn

    def __iter__(self):
        # ???
        pass

    def __next__(self):
        # ???
        pass

对我来说,这似乎是有利的,但不可能。有利,因为生成器函数通常更容易编写并且需要更少的代码。通常,我开始编写生成器函数,并且在某些时候,我需要一个迭代器对象(例如,何时generator_fn是 my 的成员,class Foo我想编写for x in my_foo而不是for x in my_foo.generator_fn(). 不可能,因为生成器函数定义了循环过程的执行流程,而迭代器对象只需提供它们的__next__接口以由未定义的“外部”执行流程请求。

我是对的还是有可能这样做?

当然,除了将所有生成的元素消耗到列表中的琐碎、消耗内存的解决方案之外。

谢谢你的帮助。

标签: pythonpython-3.xiteratorgenerator

解决方案


带有 yield 的函数是一个函数,当被调用时,它会返回一个生成器对象的实例(它是一种特定类型的迭代器)。因此,正如评论中已经提到的,您只需要做:

def generator_fn():
    x = 0
    for y in range(10):
         x += y
         yield x

iterator_from_generator_fn = generator_fn()

但是,这样做,你可能会遇到这个问题:在 Python 中重置生成器对象,因为根据定义,你只能迭代生成器一次。

您可能想要的是一个 iterable :一个__iter__方法返回一个迭代器对象的对象。像这样的东西:

class IterableFromGenerator(object):

    def __init__(self, generator_fn):
        self.generator_fn = generator_fn

    def __iter__(self):
        return generator_fn()


iterable_from_generator_fn = IterableFromGenerator(generator_fn)

推荐阅读