Как вырваться из нескольких циклов в Python?

Мне удалось преодолеть эту проблему, используя «max-age = 0» в моем заголовке Cache-Control, например:

var url = "http://www.stackoverflow.com";
var options =
  {
    // Ensure we get a fresh copy of the site every time.
    headers : {'Cache-Control' : 'max-age=0'}
  };
var response = UrlFetchApp.fetch(url, options)

Похоже, что в Google App Engine есть проблема . Кто-то открыл вопрос , однако он, кажется, был закрыт.

414
задан Mark Amery 21 April 2019 в 15:39
поделиться

9 ответов

Мой первый инстинкт должен был бы осуществить рефакторинг вложенный цикл в функцию и использование return для вспыхивания.

433
ответ дан Robert Rossney 21 April 2019 в 15:39
поделиться

Во-первых, можно также рассмотреть создание процесса получения и проверки входа функция; в той функции можно просто возвратить значение, если его корректные, и продолжают вращаться в в то время как цикл если нет. Это по существу устраняет проблему, которую Вы решили и можете обычно применяться в более общем случае (убегающий из нескольких циклов). Если Вы абсолютно должны сохранить эту структуру в своем коде, и действительно не хотите иметь дело с бухгалтерскими булевскими переменными...

можно также использовать goto следующим образом (использующий модуль Жертв первоапрельской шутки от здесь ):

#import the stuff
from goto import goto, label

while True:
    #snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": goto .breakall
        if ok == "n" or ok == "N": break
    #do more processing with menus and stuff
label .breakall

я знаю, я знаю, "Вы не должны использовать goto" и все это, но он работает хорошо в странных случаях как это.

36
ответ дан Matt J 21 April 2019 в 15:39
поделиться

keeplooping=True
while keeplooping:
    #Do Stuff
    while keeplooping:
          #do some other stuff
          if finisheddoingstuff(): keeplooping=False

или что-то как этот. Вы могли установить переменную во внутреннем цикле и проверить его во внешний цикл сразу после выходов внутреннего цикла, повредившись в подходящих случаях. Мне отчасти нравится метод GOTO, если Вы не возражаете использовать модуль Первоапрельской шутки - не Pythonic, но это действительно имеет смысл.

15
ответ дан quick_dry 21 April 2019 в 15:39
поделиться

Это не самый симпатичный способ сделать это, но по-моему, это - лучший способ.

def loop():
    while True:
    #snip: print out current state
        while True:
            ok = get_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": return
            if ok == "n" or ok == "N": break
        #do more processing with menus and stuff

я вполне уверен, Вы могли разработать что-то с помощью рекурсии здесь также, но я не знаю, является ли это хорошим вариантом для Вас.

11
ответ дан Jason Baker 21 April 2019 в 15:39
поделиться
  • 1
    Можно также объявить свойства с несвязанными универсальными типами, который делает вещи большим количеством забавы: общедоступный MyType< T> PropertyName {добираются; набор;}. При реализации метода get/метода set тип значения будет T и будет меняться, как это используется. – dthorpe 6 April 2010 в 18:24

Во-первых, обычная логика полезна.

, Если по некоторым причинам завершающиеся условия не могут быть разработаны, исключениями является план нейтрализации.

class GetOutOfLoop( Exception ):
    pass

try:
    done= False
    while not done:
        isok= False
        while not (done or isok):
            ok = get_input("Is this ok? (y/n)")
            if ok in ("y", "Y") or ok in ("n", "N") : 
                done= True # probably better
                raise GetOutOfLoop
        # other stuff
except GetOutOfLoop:
    pass

Для этого определенного примера, исключение не может быть необходимым.

На другой другой руке, у нас часто есть "Y", опции "N" и "Q" в приложениях текстового режима. Для опции "Q" мы хотим непосредственный выход. Это более исключительно.

105
ответ дан Aaron Hall 21 April 2019 в 15:39
поделиться

PEP 3136 делает предложение маркированный, повреждают/продолжают. Guido отклонил его , потому что "код, так сложный для требования этой функции, очень редок". PEP действительно упоминает некоторые обходные решения, хотя (такие как метод исключения), в то время как Guido чувствует, рефакторинг для использования возврата будет более простым в большинстве случаев.

140
ответ дан John Fouhy 21 April 2019 в 15:39
поделиться
  • 1
    CTRL+BREAK является ключом суперпрерывания, по крайней мере, в Windows. – Steve Howard 25 September 2013 в 02:02

Фактор логики цикла в итератор, который выдает переменные цикла и возвращает по завершении - вот простой пример, который излагает изображения в строках / столбцах, пока у нас не закончатся изображения или места для их размещения:

def it(rows, cols, images):
    i = 0
    for r in xrange(rows):
        for c in xrange(cols):
            if i >= len(images):
                return
            yield r, c, images[i]
            i += 1 

for r, c, image in it(rows=4, cols=4, images=['a.jpg', 'b.jpg', 'c.jpg']):
    ... do something with r, c, image ...

Это дает преимущество в разделении сложной логики цикла и обработки ...

8
ответ дан 22 November 2019 в 23:11
поделиться

Я склонен согласиться с тем, что рефакторинг в функцию обычно является лучшим подходом для такого рода ситуаций, но когда вам действительно нужно выйти из вложенных циклов, вот интересный вариант подхода с возбуждением исключений, который описал @ S.Lott. Он использует оператор Python with , чтобы повысить внешний вид исключения. Определите новый диспетчер контекста (вам нужно сделать это только один раз) с помощью:

from contextlib import contextmanager
@contextmanager
def nested_break():
    class NestedBreakException(Exception):
        pass
    try:
        yield NestedBreakException
    except NestedBreakException:
        pass

Теперь вы можете использовать этот диспетчер контекста следующим образом:

with nested_break() as mylabel:
    while True:
        print "current state"
        while True:
            ok = raw_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": raise mylabel
            if ok == "n" or ok == "N": break
        print "more processing"

Преимущества: (1) он немного чище (без явного блока try-except) и (2) вы получаете специально созданный подкласс Exception для каждого использования nested_break ; нет необходимости каждый раз объявлять собственный подкласс Exception .

51
ответ дан 22 November 2019 в 23:11
поделиться

Вот еще один подход, который является коротким. Недостатком является то, что вы можете разорвать только внешний цикл, но иногда это именно то, что вам нужно.

for a in xrange(10):
    for b in xrange(20):
        if something(a, b):
            # Break the inner loop...
            break
    else:
        # Continue if the inner loop wasn't broken.
        continue
    # Inner loop was broken, break the outer.
    break

Здесь используется конструкция for / else, описанная в: Почему python использует 'else' после циклов for и while?

Ключевой момент: только кажется, что внешний цикл всегда прерывается. Но если внутренний цикл не обрывается, то и внешний тоже.

Оператор continue - вот в чем волшебство. Оно находится в предложении for-else. По определению это происходит, если нет внутреннего прерывания. В этой ситуации continue аккуратно обходит внешнее прерывание.

190
ответ дан 22 November 2019 в 23:11
поделиться
Другие вопросы по тегам:

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