Небольшая избыточность кода в циклах while (не чистая)
Итак, в Python (хотя я думаю, что это может быть применено ко многим языкам), я часто встречаюсь с чем-то вроде этого:
the_input = raw_input("what to print?\n")
while the_input != "quit":
print the_input
the_input = raw_input("what to print?\n")
Возможно, я слишком придирчив, но мне не нравится, как строка the_input = raw_input("what to print?\n")
должна повторяться. Это уменьшает ремонтопригодность и организацию. Но я не вижу обходных путей для избежания дублирования кода, не обостряя проблему. На некоторых языках я мог бы написать что-то вроде этого:
while ((the_input=raw_input("what to print?\n")) != "quit") {
print the_input
}
Это определенно не Pythonic, и Python даже не позволяет назначать в условиях цикла AFAIK.
Этот действительный код исправляет избыточность,
while 1:
the_input = raw_input("what to print?\n")
if the_input == "quit":
break
print the_input
Но это тоже не совсем правильно. while 1
означает, что этот цикл будет работать вечно; Я использую цикл, но даю ему поддельное условие и помещая в него реальный.
Неужели я слишком придирчив? Есть лучший способ сделать это? Возможно, для этого существует некоторая языковая конструкция, о которой я не знаю?
Ответы
Ответ 1
Подумайте итераторы - например, в этом конкретном случае:
for the_input in iter(lambda: raw_input('what to print?\n'), 'quit'):
print the_input
Большинство циклов в Python, за исключением самых нижних уровней абстракций, лучше всего реализуются как циклы for
с помощью какого-то подрывного итератора, который захватывает "логику цикла" - встроенный iter
может помочь (например, здесь), иногда genexps (генераторные выражения) может, иногда стандартный библиотечный модуль itertools
приходит на помощь.
Чаще всего вы выберете код пользовательских функций генератора (те, которые используют yield
), или несколько раз (когда вам нужно действительно сложное управление состоянием) пользовательский класс итератора (один из которых определяет специальный метод __iter__
как return self
, и next
[[или __next__
в последних версиях Python]], чтобы вернуть "следующее значение из итерации).
Захват логики цикла за исключением того, что вы делаете на разных элементах, последовательно созданных самим циклом, здесь является помощником-абстракцией клавиш.