简体   繁体   English

在Python中突破while循环

[英]Breaking out of while loop in Python

I have a while loop that is reading user input. 我有一个while循环正在读取用户输入。 But I want the user to be able to break the while loop at any point, so they can go back to a main menu. 但是我希望用户可以随时中断while循环,以便他们可以返回到主菜单。

At the moment this is the only way I can do it (if statements after every point that the user may have typed '--back'. The menu.code is returned from the menu.parse function if it is changed. But then the while loop has to completely finish before it's new menu code takes effect. Is there a way of doing this without all the if statements? 目前,这是我唯一的方法(如果在用户可能键入“ --back”的每一点之后的语句。如果更改了menu.code,则会从menu.parse函数中返回。) while循环必须在新的菜单代码生效之前完全完成,没有所有的if语句,有没有办法做到这一点?

menu is a class, and there are a couple of others. menu是一类,还有很多其他menu Below is a section from the main loop. 以下是主循环的一部分。

Some of the menu class: 一些菜单类:

class Menu:

    def __init__(self):
                self.code = 'main'
                self.codememory = []

    def exit(self, input):
        if input == '--exit':
            sys.exit()

    def back(self, input):
        if input == '--back':
            if 'main' in self.codememory:
                print "should be going back"
                print self.code
                self.code = self.codememory.pop()
                print self.code

    def move(self, input):
        if input == '--new':
            self.codememory.append(self.code)
            self.code = 'new'
        if input == '--main':
            self.codememory.append(self.code)
            self.code = 'main'
        if input == '--help':
            self.codememory.append(self.code)
            self.code = 'help'

    def select(self, input):
        if input in string.digits:
            input = int(input)
            if input == 1:
                self.codememory.append(self.code)
                self.code = 'new'
            if input == 2:
                self.codememory.append(self.code)
                self.code = 'test'

    def header(self, title):
        os.system('clear')
        print "-------------------"
        print title.upper()
        print "-------------------"
        print ""

    def parse(self, input):
        self.exit(input)
        self.back(input)
        if self.code == 'new':
            return input.lower().decode('utf-8')

############################
   menu = Menu()



        while 1:

            ...

            while menu.code == 'new':
                    menu.header('save word')
                    key = menu.parse(raw_input("Norwegain: "))
                    while key in dict.keys:
                        print "word already Saved in Dictionary"
                        key = menu.parse(raw_input("Norwegain: "))
                    if menu.code == 'new':
                        val = menu.parse(raw_input("English: "))
                    if menu.code == 'new':
                        syn = menu.parse(raw_input("Synonym: "))
                    if menu.code == 'new':
                        ant = menu.parse(raw_input("Antonym: "))

            while menu.code == 'main':
                    ...

To break out of multiple loops in Python, wrap the loops in a function and return from it when you would like to leave: 要在Python中打破多个循环,请将循环包装在一个函数中,并在需要退出时从中返回:

while 1:
    def donew():
       while menu.code == 'new':
          blah ...
          while key in dict.keys:
             blah ...
             if some_condition: return
          blah ...
          val = menu.parse(raw_input("English: "))
    donew()

Raise an exception to exit the loop. 引发异常以退出循环。 This is a common enough trick in Python and the way you describe your problem makes me believe it is actually some kind of exception you are willing to manage. 这是Python中足够普遍的技巧,而您描述问题的方式使我相信这实际上是您愿意管理的某种异常。

Code may look like below: 代码如下所示:

class OutMainLoop(Exception):
    pass

while 1:
    try:
       while menu.code == 'new':
          blah ...
          while key in dict.keys:
             blah ...
             if some_condition:
                raise OutToMainLoop()
          blah ...
          val = menu.parse(raw_input("English: "))
    except OutToMainLoop:
        pass

But in this case it would certainly be even more natural to raise the exception from inside the menu class. 但是在这种情况下,从菜单类内部引发异常肯定会更加自然。

It very easy to do in Python. 在Python中非常容易做到。 The Drawback is that is makes the code flow slightly harder to follow, but your example really looks like a legitimate use of an Exception. 缺点是使代码流更难遵循,但您的示例确实看起来像是对Exception的合法使用。

With this particular code, @kriss' suggestion to use exceptions is probably reasonable. 使用此特定代码,@ kriss建议使用异常可能是合理的。 Going a little more meta, you may want to look into state machines, though. 不过,稍微多一些一些meta,您可能希望研究一下状态机。 It looks like your application is essentially a state machine, and, by using a state machine to handle transitions from one state to another, you could make your code much easier to follow and, more importantly, much easier to come back to in six months when somebody wants to add another command to it. 看起来您的应用程序本质上是一个状态机,并且通过使用状态机来处理从一种状态到另一种状态的转换,您可以使代码更易于遵循,更重要的是,可以更轻松地在六个月内返回代码当有人想向它添加另一个命令时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM