Решил поделиться с Вами своим "велосипедным" открытием и, в то же время, уточнить, насколько это безопасно, логично и рационаьно.
Суть задачи: имеется цикл, в теле которого происходит какой-либо запрос (пусть будет сетевой), который имеет свойство прерываться в связи с нестабильным соединением. Задача состоит в том, чтобы не прерывая исполнения кода, выполнить любое возможное количество повторных запросов, пока один из них не будет успешным.
Стандартное решение: обычно организуется вложенный цикл, в котором проверяется состояние, либо отлавливаются исключения и в соответствии с результатом запрос зацикливается, либо продолжается нормальное исполнение кода.
Моё решение: вместо организации вложенного цикла, определяется функция, в которой происходит запрос и в ней же проверяется состояние этого запроса. Если состояние неудовлетворительное - функция вызывается рекурсивно.
Пример:
def retrieve(something): data = get_data(something)
if not data: data = retrieve(something)
return data
Любой контроль можно добавить, как и в случае с вложенным циклом. Однако, возвращаясь к моему вопросу, покритикуйте, плох ли этот метод и чем он хуже обычного цикла?
Есть контейнер, содержащий итератор. Соответственно, к контейнеру можно применить конструкцию for p in container. Но в данном случае она не очень подходит, поскольку возвращаемые объекты нужно обрабатывать по-разному. Несколько первых, возможно, придётся вообще пропустить, а из последующих выделять определённую часть, склеивая её из нескольких последовательных объектов, и эти склеенные куски поштучно возвращать обратно в вызывающую функцию (очевидно, генератором).
Собственно вопрос: как это красиво запрограммировать? Я не придумал ничего лучше, чем в генераторе написать два цикла, читающих пакеты вручную с помощью next(). Первый цикл игнорирует все пакеты, пока не встретит пакет с определённым флажком, второй накапливает содержимое очередных пакетов, пока не встретит очередной такой флажок. Как встретит - возвращает накопленное с предыдущего флажка.
Но как-то оно некрасиво выглядит. Есть какие-нибудь более изящные способы записать эту логику? Или всё же лучше использовать один цикл for по всем объектам, а текущее состояние запоминать в дополнительных переменных?