Ответ 1
Цикл for
явно прослушивает StopIteration
.
Цель оператора for
состоит в том, чтобы перебрать последовательность, предоставленную итератором, и исключение используется, чтобы сигнализировать, что итератор теперь выполнен; for
не обнаруживает других исключений, вызванных повторением итерации объекта, только этого.
Это потому, что StopIteration
- это нормальный ожидаемый сигнал, чтобы сказать, кто из вас повторяет, что больше ничего не будет создано.
Функция генератора - это особый тип итератора; он действительно поднимает StopIteration
, когда функция выполняется (т.е. когда она возвращается, поэтому да, return None
повышает StopIteration
). Это требование итераторов; они должны поднять StopIteration
, когда они будут сделаны; на самом деле, как только a StopIteration
был поднят, попытка получить из него еще один элемент (через next()
или вызов метода .next()
(py 2) или .__next__()
(py 3) на итераторе) всегда снова поднимите StopIteration
.
GeneratorExit
является исключением для связи в другом направлении. Вы явно закрываете генератор с выражением yield
, и способ, которым Python сообщает это замыкание генератору, - это повышение GeneratorExit
внутри этой функции. Вы явно поймали это исключение внутри countdown
, его цель - дать генератору очистить ресурсы по мере необходимости при закрытии.
A GeneratorExit
не передается вызывающему; см. generator.close()
документация.