Python程序中如何正确处理TypeError及非数字输入异常
Python成绩平均器非数值输入异常捕获修复方案
原代码异常捕获不生效的核心问题
- 异常触发时机判断错误:
input()函数的返回值永远是字符串类型,直接对返回值做float()强转时,如果用户输入非数字内容(比如字母、符号),会在强转这一步直接抛出ValueError,后续写的type()类型判断代码根本没有执行机会,程序直接崩溃。 - 类型判断逻辑写反:成绩累加后的校验代码
if not type(grades) is not float是双重否定逻辑,哪怕执行到这一步,判断条件也永远不成立,不可能触发预设的TypeError抛出逻辑。 - 数据类型选择不合理:待录入的成绩数量必须是正整数,用
float()接收会允许用户输入2.5、3.2这类无意义的小数,不符合业务逻辑。 - 错误重试逻辑有隐患:输入错误时通过递归调用
GradeAverager()重新走流程,用户连续输入错误次数过多时会触发递归深度限制,导致程序栈溢出崩溃。 - 分数评级逻辑存在顺序bug:原代码先判断
average >70,80分、90分以上的成绩会直接命中第一个分支,输出错误的评级提示。
正确实现方向
- 所有数值输入环节用
try-except块包裹float()/int()强转逻辑,直接捕获强转阶段抛出的ValueError,不要在强转完成后再做类型判断。 - 补充业务规则校验:比如成绩数量必须大于0,单科成绩要在合理分数区间(比如0-100),不符合规则时提示用户重新输入。
- 用循环重试代替递归处理输入错误,避免栈溢出风险。
- 分数段判断从高到低匹配,避免高分数段被低阈值条件提前拦截。
修复后参考代码
def grade_averager(): print("\n\n*****Welcome to the Grade Averager******") while True: response = input("\n\nWould you like to average your grades? Press Y for Yes or N to exit: ").strip() if response in ["n", "N"]: print("\n\nGood Luck!\n\n") break if response not in ["y", "Y"]: print("\n\nIncorrect Entry, please input Y/N\n\n") continue # 校验录入的成绩数量 num_of_grades = 0 while True: try: num_input = input("\n\nEnter number of grades to be averaged: ").strip() num_of_grades = int(num_input) if num_of_grades <= 0: print("Please enter a positive integer!") continue break except ValueError: print("Only positive integers are allowed, please re-enter!") # 循环录入成绩 total_grades = 0 x = 0 while x < num_of_grades: try: grade = float(input(f"\n Enter Grade {x+1}: ").strip()) # 成绩区间校验,可根据需求调整分数范围 if grade < 0 or grade > 100: print("Grade should be between 0 and 100, please re-enter!") continue total_grades += grade x += 1 except ValueError: print("Only numbers are allowed, please re-enter!") average = total_grades / num_of_grades rounded_average = round(average, 1) print("\n\nYour Grade Average is: " + str(rounded_average)) # 从高到低匹配分数段 if average >= 90: print("\n Awesome Job! You are Acing this! XD\n\n") elif average >= 80: print("\n Good Job! you're getting there! :)\n\n") elif average >= 70: print("\n You are passing but should study harder :|\n\n") else: print("\n You need to go back and study! :(\n\n") if __name__ == "__main__": grade_averager()
内容的提问来源于stack exchange,提问作者Sanchesus
相关产品推荐
相关产品推荐

