Python · Day 17

异常处理与
安全成绩输入

第十七天,我第一次接触异常处理。目标不是阻止所有错误出现,而是在用户输入无法转换时接住错误、给出提示,并让程序继续等待正确输入。

第一次使用 try / except

int(input()) 遇到 abc 时无法完成整数转换,原本会让程序报错并停止。把这段代码放进 try,再用 except ValueError 接住转换错误,程序就能显示更容易理解的提示。

day17.py
try:                                              # 尝试执行可能出错的输入转换
    score = int(input("请输入成绩:"))          # 输入文字时会产生ValueError
    print("已录入成绩:", score)               # 转换成功时输出整数成绩
except ValueError:                                # 接住无法转换为整数的错误
    print("输入错误,请输入整数")               # 用清楚的提示代替程序崩溃

类型正确,不代表范围正确

输入 120 时不会进入 except,因为字符串 "120" 可以成功转换成整数。它的问题是超出成绩范围,因此还需要用 if score < 0 or score > 100 单独检查。

except ValueError 负责“能不能转换成整数”,if 负责“整数是否在允许范围”。这是两种不同的错误路线。

输入错误后继续询问

只使用一次 try / except,提示之后程序仍会结束。加入 while True 后,文字输入会进入 except,超出范围的整数会进入 if,两种情况都不会执行 break,所以程序会回到下一轮。

day17.py
while True:                                       # 持续询问直到得到有效成绩
    try:                                          # 尝试转换本轮输入
        score = int(input("请输入0到100的成绩:")) # 得到整数或产生ValueError
        if score < 0 or score > 100:             # 检查整数是否超出范围
            print("成绩必须在0到100之间")         # 范围错误时继续下一轮
        else:                                      # 类型和范围都正确时进入这里
            print("成功录入成绩:", score)       # 显示已经接受的成绩
            break                                  # 只在有效输入后结束循环
    except ValueError:                            # 处理文字等转换错误
        print("输入错误,请输入整数")             # 提示后自动继续下一轮

实际测试依次输入 abc12085:前两项分别被异常处理和范围判断拦截,85 被成功接受,随后循环结束。

把安全输入封装成函数

最后把安全录入过程放进 input_score()。有效输入出现时使用 return score,它会同时结束循环和整个函数,并把整数成绩交给外部变量,因此不再需要 break

safe_grade.py
def input_score():                              # 定义安全输入函数
    while True:                                   # 错误时不断重新询问
        try:                                      # 尝试转换用户输入
            score = int(input("请输入0到100的成绩:")) # 得到整数成绩
            if score < 0 or score > 100:         # 检查成绩范围
                print("成绩必须在0到100之间")     # 无效范围继续循环
            else:                                  # 有效成绩进入这里
                return score                         # 返回整数并结束整个函数
        except ValueError:                        # 接住整数转换错误
            print("输入错误,请输入整数")         # 提示后继续循环

函数测试依次输入 hello-1085,最终 input_score() 返回整数 85,随后 get_level(85) 返回字符串“良好”。

今天真正理解的区别

  • try:尝试执行可能发生异常的代码
  • except ValueError:接住无法完成整数转换的错误
  • if:检查已经转换成功的整数是否符合范围
  • break:只结束当前循环
  • return score:结束整个函数,并把成绩送回调用处

如果函数只用 break 结束循环,最后又没有写 return,Python 会自动返回特殊值 None。这也进一步说明了“结束循环”和“返回函数结果”不是同一件事。

今天的关键进步,是开始让程序主动面对错误:先区分转换错误与范围错误,再为每一种情况选择正确的处理路线。