Как вы называете итератор с двумя разными состояниями «готово»?

Запрашивая API с разбитым на страницы списком неизвестной длины, я обнаружил, что делаю по существу

def fetch_one(self, n):
    data = json.load(urlopen(url_template % n))
    if data is None:
        self.finished = True
        return
    for row in data:
        if row_is_weird(row):
            self.finished = True
            return
        yield prepare(row)

def work(self):
    n = 1
    self.finished = False
    while not self.finished:
        consume(self.fetch_one(n))
        n += 1

разделение между workи fetch_one, что упрощает тестирование, но сигнализация через переменные экземпляра означает, что я не могу иметь более одной работыодновременно, что отстой. Я придумал, как мне кажется, более чистое решение, но оно включает итератор с двумя состояниями «готово», и я понятия не имею, как его назвать. Я уверен, что этот шаблон существует где-то еще, поэтому я был бы признателен за указатели (или причины, почему это глупо):

class Thing(object):
    def __init__(self, gen):
        self.gen = gen
        self.finished = False

    def __iter__(self):
        return self

    def __next__(self):
        try:
            v = next(self.gen)
        except StopThisThing:
            self.finished = True
            raise StopIteration
        else:
            return v
    next = __next__

, которые я затем использовал бы как

@thinged
def fetch_one(self, n):
    data = json.load(urlopen(url_template % n))
    if data is None:
        raise StopThisThing()
    for row in data:
        if row_is_weird(row):
            raise StopThisThing()
        yield prepare(row)

def work(self):
    n = 1
    while True:
        one = self.fetch_one(n)
        consume(one)
        if one.finished:
            break
        n += 1

, так что же это за Вещь, которую я создал?

6
задан Chipaca 10 March 2012 в 22:54
поделиться