不,Python不直接支持redo。有一个选项可能会让嵌套循环变得非常糟糕,比如:for x in mylist:
while True:
...
if shouldredo:
continue # continue becomes equivalent to redo
...
if shouldcontinue:
break # break now equivalent to continue on outer "real" loop
...
break # Terminate inner loop any time we don't redo
但这意味着,在“redoable”块中,不诉诸异常、标记变量或将整个东西打包为函数,就不可能break使用外部循环。
或者,使用一个直接的while循环来复制for循环为您做的事情,显式地创建和推进迭代器。它有自己的问题(continue实际上是redo默认情况下,您必须显式地为“real”continue推进迭代器),但它们并不可怕(只要您使用continue注释,以表明您打算redo对continue,以避免混淆维护者)。要允许redo和其他循环操作,您需要执行以下操作:# Create guaranteed unique sentinel (can't use None since iterator might produce None)
sentinel = object()
iterobj = iter(mylist) # Explicitly get iterator from iterable (for does this implicitly)
x = next(iterobj, sentinel) # Get next object or sentinel
while x is not sentinel: # Keep going until we exhaust iterator
...
if shouldredo:
continue
...
if shouldcontinue:
x = next(iterobj, sentinel) # Explicitly advance loop for continue case
continue
...
if shouldbreak:
break
...
# Advance loop
x = next(iterobj, sentinel)
上面的操作也可以用try/except StopIteration:来完成,而不是用一个sentinel来包装两个参数next,但是用它来包装整个循环可能会有其他StopIteration源被捕获的风险,并且在一个有限的范围内对内部和外部的next调用都正确地执行这一操作会非常难看(比基于sentinel的方法更糟糕)。