Как заставить функцию внутри другой функции выйти из обеих функций одновременно? - PullRequest
0 голосов
/ 19 мая 2018

Я делаю программу, которая задает пользователям некоторые вопросы и использует различные функции, чтобы реагировать на то, что пользователь дает в качестве ввода.Мне нужно сделать так, чтобы, если пользователь когда-либо введет «Отмена», он не только завершит функцию, в которой он находится в данный момент, но даже функцию, которая вызвала предыдущую функцию.

def func1(x):
    func2(x+5)
    print 5
def func2(x):
    func3(x+5)
    print 5
def func3(x):
    print x
    return

func1(20)
print 10

# 30
# 5
# 5
# 10

Так что в настоящее время это будетпечать 30, выход из func3, печать 5, выход из func2, печать 5, выход из func1.Мне нужен способ, чтобы он просто остановился после того, как func3 напечатает 30. Любые идеи?

Таким образом, желаемый результат будет.

#30
#10

Редактировать: Это очень упрощенная версия, они нене вводите отмену в этом конкретном коде.Это было бы в raw_input.

1 Ответ

0 голосов
/ 19 мая 2018

Поднятие exception выходит из стека функций так же, как вы описываете.Таким образом, вы можете иметь самую внешнюю функцию try-expect всех внутренних функций.Если какая-либо из внутренних функций вызовет exception, она будет пузыриться (то есть не будет выполнять любой последующий код в стеке), пока не достигнет except.

def func1(x):
    try:
      func2(x+5)
      print 5
    except:
      pass  

def func2(x):
    func3(x+5)
    print 5

def func3(x):
    print x
    raise("Foo")  # user's input should drive this.
    return

func1(20)
print 10
* 1007 самой внешней функции.* Доходит до func3 нормальным способом.func3 однако говорит, что не хочет, чтобы нормальный поток выполнения равнялся func2, который каскадно переходит к func1.

Если вы не хотите изменять содержимое функции, вы можете использовать следующий декоратор.Также есть исправления, упомянутые в комментариях.

class UserAbort(Exception):
    pass

def swallow(f):
    def wrapper(*args):
        try:
            f(*args)
        except UserAbort:
            pass
    return wrapper

@swallow
def func1(x):
    func2(x+5)
    print 5

def func2(x):
    func3(x+5)
    print 5

def func3(x):
    print x
    raise UserAbort  # user's input should drive this.
    return

func1(20)
print 10
...