Запрашивая 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
, так что же это за Вещь, которую я создал?