自学Python第13天:异常处理——我终于能让程序不随便崩溃了
自学Python第13天:异常处理——我终于能让程序不随便崩溃了
新手向 | 2026-09-7
前12篇,我写了变量、判断、循环、函数、列表、字典、集合。代码跑通了就开心,报错了就改。但我从来没想过一个问题:
如果用户不按套路输入怎么办?
比如写一个“输入年龄”的程序,用户输入了“abc”或者直接按回车,程序就会报错崩溃。这种崩溃不是代码逻辑错了,是用户的输入让程序无法处理。
今天学的异常处理,就是解决这个问题的——让程序遇到错误时不崩溃,而是“接住”这个错误,给用户一个友好的提示。
一、错误和异常是两回事
学异常处理之前,先搞清楚两个概念:
1. 语法错误(Error)
代码写错了,Python认不出来。比如:
# 漏了冒号
if age > 18
print("成年了")
这种错误代码根本跑不起来,Python直接报错,你必须修好才能继续。
2. 运行时异常(Exception)
代码语法没问题,但运行到某一步出错了。比如:
age = int(input("请输入年龄:"))
用户输入了"abc",int("abc")就会报ValueError,程序直接崩溃退出。
语法错误躲不掉,但运行时异常可以”接住“————这就是异常处理做的事。
二、常见的异常类型
我整理了一些比较常见的异常:
| 异常类型 | 触发场景 |
|---|---|
| SyntaxError | 语法写错了(少冒号、括号不匹配) |
| NameError | 变量未定义或拼写错误 |
| TypeError | 不同类型之间做了不允许的操作(字符串+数字) |
| ValueError | 值不合法(int("abc")) |
| IndexError | 列表/字符串索引超出范围 |
| KeyError | 字典里没有这个键 |
| ZeroDivisionError | 除以0 |
| FileNotFoundError | 文件不存在 |
这些报错我之前几乎都遇到过。最烦的不是报错,而是程序一崩就全没了。
三、try-except:把异常”接住“
核心语法:
try:
# 可能出错的代码
except 异常类型:
# 出错时执行的代码
看一个例子:
try:
age = int(input("请输入你的年龄:"))
print(f"明年你就{age + 1}岁了")
except ValueError:
print("输入错误,请输入数字!")
如果用户输入18,程序正常运行:
请输入你的年龄:18
明年你就19岁了
如果用户输入abc,程序不会崩溃,而是执行except里的代码:
请输入你的年龄:abc
输入错误,请输入数字!
这就是异常处理最核心的价值————让程序在出错时”有话说“,而不是直接消失。
四、捕获多种异常
一段代码可能触发多种异常。比如从用户输入里拿数字然后做除法:
try:
num = int(input("请输入一个整数:"))
result = 10 / num
print(f"10除以{num}等于{result}")
except ValueError:
print("输入的不是有效整数")
except ZeroDivisionError:
print("不能除以0")
用户输入0时触发ZeroDivisionError,输入abc时触发ValueError.两个异常分别处理,提示也更准确。
五、一个我踩过的坑:把所有异常混在一起抓
新手容易犯的错误是:不管什么异常,都用一个except:抓走。就像把所有垃圾都装进一个袋子里,最后你根本不知道袋子里有什么。
try:
age = int(input("请输入年龄:"))
result = 100 / age
except:
print("出错了!")
这样虽然程序不会崩,但你失去了对具体问题的判断力————到底用户输入了字母,还是输入了0?
更合理的做法是分别捕获常见的异常,最后用 except Exception as e 兜底:
try:
age = int(input("请输入年龄:"))
result = 100 / age
except ValueError:
print("请输入数字!")
except ZeroDivisionError:
print("年龄不能为0!")
except Exception as e:
print(f"未知错误:{e}")
这样每个问题都有对应的提示,最后一个Exception用来负责处理你没预料到的意外情况。
六、else和finally
else:没有异常时执行;
finally:无论有没有异常都执行。
try:
num = int(input("请输入数字:"))
except ValueError:
print("输入错误!")
else:
print(f"你输入的是{num}")
finally:
print("程序运行结束")
用户输入5:
请输入数字:5
你输入的是5
程序运行结束
用户输入abc:
请输入数字:abc
输入错误!
程序运行结束
finally在做文件操作、数据库连接时非常有用————不管代码有没有报错,文件总要关掉、连接总要断开。
七、raise:自己主动抛出异常
有时候,代码语法没错,但业务逻辑上不对。比如用户注册时密码少于6位,python不会自动报错,但你可以用raise主动抛出异常。
def register(username, password):
if len(password) < 6:
raise ValueError("密码长度不能少于6位!")
print(f"用户{username}注册成功!")
try:
register("张三", "123")
except ValueError as e:
print(e)
运行结果:
密码长度不能少于6位!
八、综合示例:支持连续计算的简易计算器
把今天学的东西串起来:
import re
def calculate():
print("简易计算器(输入 q 退出)")
print("支持格式:3 + 5、10 / 2")
while True:
exp = input("\n请输入算式:")
if exp.lower() == "q":
print("再见!")
break
try:
# 用正则表达式解析:数字 运算符 数字
match = re.match(r"(\d+)\s*([+\-*/])\s*(\d+)", exp)
if not match:
raise ValueError("格式错误,请使用:数字 运算符 数字")
num1 = float(match.group(1))
op = match.group(2)
num2 = float(match.group(3))
if op == "+":
result = num1 + num2
elif op == "-":
result = num1 - num2
elif op == "*":
result = num1 * num2
elif op == "/":
if num2 == 0:
raise ZeroDivisionError("除数不能为0!")
result = num1 / num2
else:
raise ValueError("不支持的运算符")
print(f"{num1} {op} {num2} = {result:.2f}")
except ValueError as e:
print(f"输入错误:{e}")
except ZeroDivisionError as e:
print(f"计算错误:{e}")
except Exception as e:
print(f"未知错误:{e}")
calculate()
运行结果:
简易计算器(输入 q 退出)
支持格式:3 + 5、10 / 2
请输入算式:3 + 5
3.0 + 5.0 = 8.00
请输入算式:10 / 0
计算错误:除数不能为0!
请输入算式:abc
输入错误:格式错误,请使用:数字 运算符 数字
请输入算式:q
再见!
这段代码包含了:
·try-except 捕获多种异常
·raise 主动抛出业务异常
·except Exception as e 兜底未知错误
·while 循环让计算机持续运行
小结
今天学的东西,整理成一张速查表:
语法 作用 示例
| try-except | 捕获异常,防止程序崩溃 | except ValueError: |
|---|---|---|
| except Exception as e | 捕获所有异常(兜底) | except Exception as e: |
| else | 没有异常时执行 | else: print("成功") |
| finally | 无论是否异常都执行 | finally: f.close() |
| raise | 主动抛出异常 | raise ValueError("错误信息") |
下一篇我打算学文件操作——让程序能把数据保存下来,而不是每次运行都从头开始。
如果你也在学Python,欢迎在评论区告诉我你今天学到了什么,或者遇到了什么报错,一起交流!
相关文章:
- 自学Python第1天:从下载PyCharm和安装环境开始
- 自学Python第2天:敲下第一行print("Hello World"),我遇到了3个问题
- 自学Python第3天:数据类型、转换、运算符——我终于搞懂了为什么"1"和1不一样
- 自学Python第4天:字符串的三种定义方式、拼接、格式化
- 自学Python第5天:数据输入(input语句)、布尔类型、比较运算符和逻辑运算符
- 自学Python第6天:if判断、if-else、if-elif-else和嵌套判断
- 自学Python第7天:for循环和while循环——我终于让程序能重复做一件事了
- 自学Python第8天:函数——我终于能把重复的代码“打包”起来了
- 自学Python第9天:列表——我终于能把一堆东西放在一起了
- 自学Python第10天:元组和切片——我终于搞懂了什么是“不可变的列表”
- 自学Python第11天:字典——我终于能让程序像查字典一样找东西了
- 自学Python第12天:集合——我终于能把重复的东西自动去掉了

浙公网安备 33010602011771号