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可以处理列表操作,但是当它的迭代器调用它将返回一个生成器?
这取决于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)
并将其用作没有生成器优点和缺点的列表。