这是实现迭代器的好方法吗?

时间:2019-07-21 18:42:36

标签: python

我对优良作法有疑问。 所以说我们有一些要用作迭代器的类。 该类应首先返回一些标头,然后返回其块。 对于这种情况,我看到两种方法:

  1. 第一个是“经典”。自行返回 iter 方法,并在 next 方法中添加一些逻辑,例如:
def __next(self):
    if not self._header_was_returned:
        self._header_was_returned = True
        return self._header
    if self._index >= self._count_blocks:
        raise StopIteration
    block = self._blocks[self._index]
    self._index += 1
    return block
  1. 或者另一个,在这种情况下,使用更少的代码,只需实现 iter 方法:
def __iter__(self):
    yeild self._header
    for block in self._blocks:
        yield block

另一种情况是创建某个类IteratorForMyBlockClass并在那里实现`` _next `''方法,但第一种情况与之类似。

已更新:

摘自“ Fluent Python”(第14章)。 主类是可迭代的(但不是迭代器)。 主类应在IteratorClass方法中返回一些__iter__。 在Iterator类中,我应该添加一些逻辑:

class MainClass:
    def __init__(self, header, blocks):
        self._header = header
        self._blocks = blocks
    def __iter__(self):
        return MainClassIterator(self._header, self._blocks)

class MainClassIterator:
    def __init__(self, header, blocks):
        self._header = header
        self._blocks = blocks
        self._index = 0
        self._header_was_returned = False
    def __iter__(self):
        return self
    def __next__(self):
        if not self._header_was_returned:
             self._header_was_returned = True
             return self._header
        if self._index >= len(self._blocks):
             raise StopIteration        
        block = self._blocks[self._index]
        self._index += 1
        return block

这是一个好的解决方案吗?

1 个答案:

答案 0 :(得分:2)

您实际上并不需要MainClassIterator。由于生成器函数总是返回迭代器,因此一个简单的解决方案是将此__iter__放在MainClass中:

def __iter__(self):
    yield self._header
    yield from self._blocks