маленькое дублирование кода в циклах с условием продолжения (не чувствует себя чистым),

Так, в 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 подразумевает, что этот цикл будет работать навсегда; я использую цикл, но даю ему поддельное условие и помещаю реальное в нем.

Я слишком придирчив? Существует ли лучший способ сделать это? Возможно, существует некоторая конструкция языка, разработанная для этого, что я не знаю о?

11
задан tshepang 14 May 2014 в 19:41
поделиться

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]] для возврата "следующего значения из итерации).

Захват логики цикла, помимо того, что вы делаете над различными элементами, последовательно производимыми самим циклом, является здесь ключевой абстракцией-помощником!

30
ответ дан 3 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: