【问题标题】:Program prints twice after user input restarts the program用户输入重新启动程序后程序打印两次
【发布时间】:2020-09-03 23:52:21
【问题描述】:

条件语句后的打印函数在用户输入导致异常并重新启动程序时打印两次。我没有看到我在哪里调用了两次变量。

# -*- coding: utf-8 -*-

def start():
    concept = ("Concept: ")
    global grade
    while True:
        try:
            grade = float(input("something: "))
            break
        except ValueError:
            print("please type numbers")
            start()
            break
        finally:
            if grade > 100:
                print("grade exceeds")
                start()
                break
            elif grade < 0:
                print("grade deficit")
                start()
                break
            elif grade >= 90 and grade <= 100:
                print(concept + "A")
            elif grade >= 80 and grade <= 89:
                print(concept + "B")
            elif grade >= 70 and grade <= 79:
                print(concept + "C")
            elif grade >= 60 and grade <= 69:
                print(concept + "D")
            elif grade >= 0 and grade <= 59:
                print(concept + "F")
            else:
                pass

start()

感谢您提供的任何帮助。

【问题讨论】:

  • 不要使用递归进行输入验证。
  • 请提供导致错误输出的输入,以及它导致的输出。
  • 请提供预期的minimal, reproducible example。显示中间结果与您的预期不同的地方。将您的测试数据作为程序的一部分包含在内,并正确跟踪执行和数据流。请参阅此lovely debugging site 寻求帮助。
  • 由于您在 finally: 块中打印结果,因此无论是否发生异常都会打印。
  • 你做过调试吗?我建议阅读ericlippert.com/2014/03/05/how-to-debug-small-programs

标签: python python-3.x function exception conditional-statements


【解决方案1】:

不要将打印结果的代码放在finally() 块中。无论是否有异常都会执行,因此当递归调用返回时,它会再次执行该代码。它应该在try 块中,因此在出现错误时将被跳过。

也不需要while 循环,因为你总是要摆脱它;您正在使用递归来重复它。

grade 不需要是全局变量。

你不应该有像and grade &lt;= 89 这样的测试。之前的elif 已经确保它小于90。您的测试将89.5 之类的情况排除在范围之外(如果您只输入整数,请使用int() 而不是float())。

def start():
    concept = ("Concept: ")
    try:
        grade = float(input("something: "))
        if grade > 100:
            print("grade exceeds")
            start()
            break
        elif grade < 0:
            print("grade deficit")
            start()
            break
        elif grade >= 90:
            print(concept + "A")
        elif grade >= 80:
            print(concept + "B")
        elif grade >= 70:
            print(concept + "C")
        elif grade >= 60:
            print(concept + "D")
        else:
            print(concept + "F")
    except ValueError:
        print("please type numbers")
        start()

start()

但更一般地说,你不应该像这样使用递归,而应该使用循环。

def start():
    concept = "Concept: "
    while True:
        try:
            grade = float(input("something: "))
            break
        except ValueError:
            print("Please type numbers")
    if grade > 100:
        print("grade exceeds")
        start()
        break
    elif grade < 0:
        print("grade deficit")
        start()
        break
    elif grade >= 90:
        print(concept + "A")
    elif grade >= 80:
        print(concept + "B")
    elif grade >= 70:
        print(concept + "C")
    elif grade >= 60:
        print(concept + "D")
    else:
        print(concept + "F")

【讨论】:

  • 你好。感谢您的回答。我做了这样的事情,它解决了我的问题。我认为问题在于我按照您所说的做了并且还在块之后调用了启动函数。无论如何,它运行良好。
【解决方案2】:

您的start() 函数每次执行Except 块时都会递归。由于grade 是一个全局变量,而finally 块即使在异常块执行时也始终运行,因此您将获得与异常块执行次数相等的重复打印语句数。

换句话说,如果出现错误,然后用户输入了一些有效输入,那么 finally 块的其余部分将使用该原始输入再次触发。因为finally 块将始终触发,即使在引发异常之后也是如此。

【讨论】:

    猜你喜欢
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多