给定以下代码(不起作用):
while True:
# Snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok.lower() == "y": break 2 # This doesn't work :(
if ok.lower() == "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"选项,我们要立即退出。这是比较特殊的。
将循环逻辑分解为迭代器,迭代器产生循环变量并在完成时返回——这里有一个简单的迭代器,它将图像按行/列排列,直到我们用完图像或找不到放置它们的位置:
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 ...
这样做的优点是将复杂的循环逻辑和处理分开。
首先,您还可以考虑将获取和验证输入的过程作为一个函数;在该函数中,如果值正确,则返回值,如果不正确,则继续在while循环中旋转。这本质上避免了您解决的问题,并且通常可以应用于更一般的情况(打破多个循环)。如果你一定要在代码中保留这个结构,并且真的不想处理记帐布尔值……
你也可以用下面的方式使用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”之类的,但它在这种奇怪的情况下很管用。