Мне удалось преодолеть эту проблему, используя «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 есть проблема . Кто-то открыл вопрос , однако он, кажется, был закрыт.
Мой первый инстинкт должен был бы осуществить рефакторинг вложенный цикл в функцию и использование return
для вспыхивания.
Во-первых, можно также рассмотреть создание процесса получения и проверки входа функция; в той функции можно просто возвратить значение, если его корректные, и продолжают вращаться в в то время как цикл если нет. Это по существу устраняет проблему, которую Вы решили и можете обычно применяться в более общем случае (убегающий из нескольких циклов). Если Вы абсолютно должны сохранить эту структуру в своем коде, и действительно не хотите иметь дело с бухгалтерскими булевскими переменными...
можно также использовать 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" и все это, но он работает хорошо в странных случаях как это.
keeplooping=True
while keeplooping:
#Do Stuff
while keeplooping:
#do some other stuff
if finisheddoingstuff(): keeplooping=False
или что-то как этот. Вы могли установить переменную во внутреннем цикле и проверить его во внешний цикл сразу после выходов внутреннего цикла, повредившись в подходящих случаях. Мне отчасти нравится метод GOTO, если Вы не возражаете использовать модуль Первоапрельской шутки - не Pythonic, но это действительно имеет смысл.
Это не самый симпатичный способ сделать это, но по-моему, это - лучший способ.
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
я вполне уверен, Вы могли разработать что-то с помощью рекурсии здесь также, но я не знаю, является ли это хорошим вариантом для Вас.
Во-первых, обычная логика полезна.
, Если по некоторым причинам завершающиеся условия не могут быть разработаны, исключениями является план нейтрализации.
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" мы хотим непосредственный выход. Это более исключительно.
PEP 3136 делает предложение маркированный, повреждают/продолжают. Guido отклонил его , потому что "код, так сложный для требования этой функции, очень редок". PEP действительно упоминает некоторые обходные решения, хотя (такие как метод исключения), в то время как Guido чувствует, рефакторинг для использования возврата будет более простым в большинстве случаев.
Фактор логики цикла в итератор, который выдает переменные цикла и возвращает по завершении - вот простой пример, который излагает изображения в строках / столбцах, пока у нас не закончатся изображения или места для их размещения:
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 ...
Это дает преимущество в разделении сложной логики цикла и обработки ...
Я склонен согласиться с тем, что рефакторинг в функцию обычно является лучшим подходом для такого рода ситуаций, но когда вам действительно нужно выйти из вложенных циклов, вот интересный вариант подхода с возбуждением исключений, который описал @ 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
.
Вот еще один подход, который является коротким. Недостатком является то, что вы можете разорвать только внешний цикл, но иногда это именно то, что вам нужно.
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
аккуратно обходит внешнее прерывание.