Python如何将方法的结果转换为生成器

Jam*_*Lin 6 python iterator generator

我有以下继承:

class Processor(object):
    def get_listings(self):
        """
        returns a list of data
        """
        raise NotImplemented()

    def run(self):
        for listing in get_listings():
           do_stuff(listing)

class DBProcessor(Processor):
    def get_listings(self):
        """
        return a large set of paginated data
        """
        ...
        for page in pages:
            for data in db.fetch_from_query(...):
                yield data
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但是这会失败len(self.get_listings())或任何其他列表操作.

我的问题是如何重构我的代码DBProcessor.get_listings可以处理列表操作,但是当它的迭代器调用它将返回一个生成器?

MSe*_*ert 0

这取决于list您想要支持哪些操作。其中一些在默认情况下只会消耗生成器iter。

如果您事先知道操作的结果(例如len),您可以通过创建 GeneratorContainer 来绕过它:

class GeneratorContainer():
    def __init__(self, generator, length):
        self.generator = generator
        self.length = length

    def __iter__(self):
        return self.generator

    def __len__(self):
        return self.length

result = GeneratorContainer(DBProcessor().get_listings(), length) 
# But you need to know the length-value.
Run Code Online (Sandbox Code Playgroud)

然后调用len将不会尝试迭代生成器。但您始终可以创建一个列表,这样数据就不会耗尽:

result = list(DBProcessor().get_listings())
Run Code Online (Sandbox Code Playgroud)

并将其用作没有生成器优点和缺点的列表。