Лучший способ получить возвращаемое значение из генератора питона
Начиная с Python 3.3, если функция генератора возвращает значение, оно становится значением для вызванного исключения StopIteration. Это можно собрать несколькими способами:
Значениеyield from
Выражение, которое подразумевает, что включающая функция также является генератором.Завершение звонкаnext()
или же.send()
в блоке try / КромеОднако, если я просто хочу перебрать генератор в цикле for (самый простой способ), то, похоже, нет способа собрать значение исключения StopIteration и, следовательно, возвращаемое значение. Я использую простой пример, в котором генератор выдает значения и в конце возвращает какую-то сводку (промежуточные итоги, средние значения, временная статистика и т. Д.).
for i in produce_values():
do_something(i)
values_summary = ....??
Один из способов - сам обработать цикл:
values_iter = produce_values()
try:
while True:
i = next(values_iter)
do_something(i)
except StopIteration as e:
values_summary = e.value
Но это отбрасывает простоту цикла for. Я не могу использоватьyield from
поскольку для этого требуется, чтобы вызывающий код сам по себе был генератором. Есть ли более простой способ, чем показанный выше цикл for roll -’s-own?
Объединяя ответы от @Chad S. и @KT, проще всего превратить мою функцию генератора в класс с использованием протокола итератора:
class ValueGenerator():
def __iter__(self):
yield 1
yield 2
# and so on
self.summary = {...}
vg = ValueGenerator()
for i in vg:
do_something(i)
values_summary = vg.summary
И ответ @Ferdinand Beyer будет самым простым, если я не смогу рефакторировать производителя стоимости.