Выход из цикла while в Python - PullRequest
1 голос
/ 09 марта 2012

У меня есть цикл while, который читает пользовательский ввод. Но я хочу, чтобы пользователь мог разорвать цикл while в любой точке, чтобы он мог вернуться в главное меню.

На данный момент это единственный способ, которым я могу это сделать (если операторы после каждой точки, которые пользователь мог набрать, --back). Menu.code возвращается из функции menu.parse, если он изменяется. Но тогда цикл while должен полностью завершиться, прежде чем его новый код меню вступит в силу. Есть ли способ сделать это без всех операторов if?

menu - это класс, и есть пара других. Ниже приведен раздел из основного цикла.

Некоторые из меню класса:

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':
                    ...

Ответы [ 3 ]

3 голосов
/ 09 марта 2012

Чтобы разорвать несколько циклов в 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()
1 голос
/ 09 марта 2012

С этим конкретным кодом, @kriss предлагает использовать исключения, вероятно, разумно.Пройдя немного больше мета, вы, возможно, захотите заглянуть в конечные автоматы.Похоже, что ваше приложение по сути является конечным автоматом, и, используя конечный автомат для обработки переходов из одного состояния в другое, вы могли бы значительно упростить отслеживание своего кода и, что более важно, вернуться к нему через шесть месяцевкогда кто-то хочет добавить к нему другую команду.

1 голос
/ 09 марта 2012

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

Код может выглядеть следующим образом:

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

Но в этом случае, безусловно, было бы еще более естественным поднять исключение из внутри класса меню.

Это очень легко сделать в Python. Недостаток в том, что выполнение кода немного усложняется, но ваш пример действительно выглядит как законное использование исключения.

...