【问题标题】:How to make a function inside another function quit both functions at once?如何使另一个函数中的函数同时退出两个函数?
【发布时间】:2018-05-19 06:55:56
【问题描述】:

我正在制作一个程序,它会询问用户一些问题,并使用不同的功能来对用户输入的内容做出反应。我需要这样做,如果用户键入“取消”,它不仅会结束他们当前所在的函数,甚至会结束调用先前函数的函数。

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

【问题讨论】:

  • 抛出异常并捕获它?
  • 使用'type'会怎样取消?
  • “他们目前在”:用户一个函数是什么意思?这对我来说没有意义。为什么不给出你所说的输入代码的例子呢?

标签: python python-2.7 function


【解决方案1】:

引发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

它以正常方式到达func3。但是func3 表示它不希望正常执行流到func2,后者将其级联到func1

如果您不想更改函数的内容,可以使用以下装饰器。它还具有 cmets 中提到的更正。

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

【讨论】:

  • 你确定 raise("Foo") 是有效的 Python 吗?
  • raise 不是一个函数,而是一个语句,应该作为 raise Exception() 调用 - 它仅适用于您的示例,因为 (...) 被视为一个分组语句。此外,使用纯 except 捕获所有异常是一种不好的做法,因为它会捕获键盘中断和其他系统/意外异常,在大多数情况下您不想像这样捕获。
  • @zwer。另外,我建议定义一个自定义标签类型,如class UserPressedCancel(Exception): pass,这样可以避免因捕获意外异常类型而导致的任何并发症。
  • 谢谢。语法错误对我来说似乎并不明显!
猜你喜欢
  • 2019-03-24
  • 2022-01-26
  • 2010-12-19
  • 2018-12-19
  • 2020-06-12
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多