Python - 使用`while`,`try`,`if`和`except`语句打破深层嵌套循环

时间:2015-05-20 04:47:46

标签: python if-statement while-loop nested try-catch

这是我的代码,它解决了给定用户输入a, b, c的二次方程式。但是,我想检查不正确的用户输入。如果用户输入除浮动之外的任何内容,则用户将遇到print "Not a valid input. Try again.\n",然后是函数quadratic2()的循环。但是,此程序是较大程序的一部分,因此我希望用户可以选择键入"next"来终止此功能并继续。我的问题是我要求3个用户输入,但我希望"next"输入是第一个输入a。这非常有效,直到用户输入随机字符串,导致ValueError。一旦发生这种情况,我的代码不想循环回来检查输入是否为next。请帮我!我认为这个代码嵌套的方式让我感到困惑。

def retest3():
    print "Type in another a, b, and c. Or type \"Next\" to move on."
def quadratic1():
    print ("This program calculates the zeroes of a quadratic equation."
    "\nPlease enter a, b, and c, hitting \"Enter\" after each one: ")
def quadratic2():
    while 1 == 1:
        a = (raw_input())
        if "next" == a.lower():
            ontonextthing()
            return 1 == 0
        else:
            try:
                a = float(a)
            except ValueError:
                print "Not a valid input. Try again.\n"
                quadratic2()
            try:
                b = float(raw_input())
            except ValueError:
                print "Not a valid input. Try again.\n"
                quadratic2()
            try:
                c = float(raw_input())
            except ValueError:
                print "Not a valid input. Try again.\n"
                quadratic2()

            if b**2-4*a*c>0:
                root1=(-b+math.sqrt(b**2-4*a*c))/(2*a)
                root2=(-b-math.sqrt(b**2-4*a*c))/(2*a)
                print ("First Root: {0}\nSecond Root: {1}".format(root1,root2))
            else:
                print ("The discriminant is negative, so your"
                " roots will contain \"i\".")
                disc1=(b**2-4*a*c)
                disc2=-disc1
                sqrtdisc2=(math.sqrt(disc2))/(2*a)
                b2=(-b)/(2*a)
                print ("{0} + {1}i".format(b2, sqrtdisc2))
                print ("{0} - {1}i\n".format(b2, sqrtdisc2))
        retest3()   

quadratic1()
quadratic2()

2 个答案:

答案 0 :(得分:3)

  

这非常有效,直到用户输入随机字符串,导致ValueError。一旦发生这种情况,我的代码不想循环回来检查输入是否是下一个。

好像你想要continue statement

        try:
            b = float(raw_input())
        except ValueError:
            print "Not a valid input. Try again.\n"
            continue

continue语句将您带回while循环的开头(下一次迭代)。目前你正在调用quadratic2(),它使你的函数递归,而不是你想要的。

因为它是递归的,当你收到你的Exception它会退出当前函数,但因为你正在使用递归,你只需返回到你在中间的前一个函数(这是相同的函数)。因此,您键入的下一个输入可以通过

进行解析
b = float(raw_input())

而不是

a = (raw_input())

答案 1 :(得分:1)

"真实"您的问题的解决方案是首先不要使用深层嵌套的构造。深度嵌套的语句使您的代码难以阅读,难以测试,难以维护且难以重用。此外,您将倾向于复制代码,这是不好的。特别是在Python中,深度嵌套会让你计算空格以使缩进正确,这实际上是一个痛苦的问题。

将代码分解为函数,并遵循"单一责任原则"通过让一个函数完成一件事。这有几个好处:

  1. 你不必在脑子里记住太多东西。专注于一个小问题,并完成它。
  2. 你可以在函数的早期return,所以你可以在很多情况下避免嵌套。
  3. 您可以在函数中重复使用代码。
  4. 您没有重复的代码:如果您想更改特定的行为,请在一个功能中更改一个功能而不是多个位置。
  5. 您可以单独测试您的功能,确保它们做正确的事。
  6. 在您的情况下,quadratic2函数执行了很多操作:

    • 它运行一个"主循环"
    • 它读取命令的用户输入
    • 调度命令
    • 它读取值的用户输入
    • 处理无效的用户输入
    • 它进行计算
    • 将结果显示给用户

    现在我并不是说你需要一个函数用于上面列出的每个细节,但很明显这个函数做得太多了。

    有关如何分解的示例:

    • 为主循环和调度命令创建一个函数。让命令(例如" next")在不同的函数中处理。
    • 从用户写入一个要在float中读取的函数,并将其调用三次,而不是重复三次try...except代码。这样做的另一个好处是,您可以增强此功能以在循环中运行,以便要求用户重复输入一个值,而不必像当前解决方案那样重新开始。

    其他提示:

    • 请勿在{{1​​}},elsereturnraise之后使用break。没有必要,因为无论如何都不会达到下一个语句,你可以保存一个嵌套级别。
    • 请勿使用continue1==1等令人困惑的表达方式。这只是撰写1==0True的复杂方式。在您的示例中,它应该改为Falsewhile True