Обновление: Все, что я действительно хотел, было зелеными .
Примечание: Этот вопрос немного мутировал, когда люди отвечали и заставляли меня «повышать ставки», поскольку мои тривиальные примеры имели тривиальные упрощения; вместо того, чтобы продолжать мутировать это здесь, я отвечу на вопрос, когда у меня это будет яснее в голове, согласно предложению Алекса.
Генераторы Python - вещь прекрасная, но как я могу легко разбить один на модули (структурированное программирование)? Я действительно хочу PEP 380 , или хотя бы что-то сопоставимое по синтаксической нагрузке, но в существующем Python (например, 2.6)
В качестве (по общему признанию, глупого) примера возьмем следующее:
def sillyGenerator():
for i in xrange(10):
yield i*i
for i in xrange(12):
yield i*i
for i in xrange(8):
yield i*i
Будучи горячим сторонником СУХОЙ, я замечаю здесь повторяющуюся модель и вычленяю ее в метод:
def quadraticRange(n):
for i in xrange(n)
yield i*i
def sillyGenerator():
quadraticRange(10)
quadraticRange(12)
quadraticRange(8)
... что, конечно, не работает. Родитель должен вызвать новую функцию в цикле, чтобы получить результаты:
def sillyGenerator():
for i in quadraticRange(10):
yield i
for i in quadraticRange(12):
yield i
for i in quadraticRange(8):
yield i
... что даже дольше, чем раньше!
Если я хочу вставить часть генератора в функцию, мне всегда нужна эта довольно многословная оболочка из двух строк для ее вызова. Становится хуже, если я хочу поддержать send ():
def sillyGeneratorRevisited():
g = subgenerator()
v = None
try:
while True:
v = yield g.send(v)
catch StopIteration:
pass
if v < 4:
# ...
else:
# ...
И это без учета передачи исключений. Один и тот же шаблон каждый раз! Тем не менее, нельзя применять DRY и включать этот идентичный код в функцию, потому что ... вам нужен шаблон для его вызова! Я хочу что-то вроде:
def sillyGenerator():
yield from quadraticRange(10)
yield from quadraticRange(12)
yield from quadraticRange(8)
def sillyGeneratorRevisited():
v = yield from subgenerator()
if v < 4:
# ...
else:
# ...
У кого-нибудь есть решение этой проблемы? У меня есть попытка первого прохода, но я хотел бы знать, что придумали другие. В конечном счете, любое решение должно будет иметь дело с примерами, когда главный генератор выполняет сложную логику на основе результата данных, отправленных в генератор, и потенциально делает очень большое количество обращений к субгенераторам: мой вариант использования - это генераторы, используемые для реализации длительные, сложные конечные автоматы.