还在让程序一报错就崩溃?
给你的程序,加个安全网
try/except · 异常处理
📦 3 PARTS + CONCLUSION
👉 滑动
这是基础篇第9篇。前面我们学了变量、循环、字符串、列表字典集合、argparse、正则、datetime。今天学一个让程序「不轻易崩溃」的技能:异常处理(try/except)。
你有没有遇到过这种崩溃:程序跑得好好的,突然甩出一大段红色报错(Traceback),然后整个程序挂了?比如用户输入了个「abc」你却拿它当数字用,或者要读的文件根本不存在。
异常处理就是来解决这个的——提前预判「这里可能会出错」,出错时优雅地兜住,给用户一个友好的提示,而不是让程序直接崩掉。
Python 里的错误分两大类:
1. 语法错误(SyntaxError):代码写错了,比如少个冒号、括号没配对。这种没法用 try/except 捕获,因为程序根本没法运行,只能在写代码时改对。
2. 执行期异常(Exceptions):代码语法没错,但运行时出错了。比如 1 / 0(除零)、int("abc")(把非数字转整数)、读不存在的文件。这些才是 try/except 能捕获的对象。
常见的内置异常类型(记几个常用的):ValueError(值不对)、TypeError(类型不对)、ZeroDivisionError(除以零)、KeyError(字典键不存在)、IndexError(列表下标越界)、FileNotFoundError(文件不存在)。
try:
x=1/0
exceptZeroDivisionError:
print("不能除以零")
把可能出错的代码放在 try 里,出错时跳转到 except 执行兜底逻辑,程序就不会崩了。
try:
num=int("abc")
exceptValueErrorase:
print(f"转换失败: {e}")
except 后面写具体的异常类型,as e 把异常对象绑到变量 e,能拿到错误详情。
d={"name":"飞污熊","age":18}
try:
print(d["city"])
exceptKeyError:
print("键不存在")
exceptZeroDivisionError:
print("除以零")
一个 try 后面可以跟多个 except,不同的异常类型走不同的兜底逻辑,按顺序从上往下匹配。
try:
num=int("123")
exceptValueError:
print("不是数字")
else:
print(f"转换成功: {num}")
else 在 try 没有抛出异常时才执行。它和 except 是互补的:有异常走 except,没异常走 else。
try:
f=open("不存在的文件.txt")
exceptFileNotFoundError:
print("文件不存在")
finally:
print("这行一定会执行")
finally 在无论是否异常都会执行,常用于清理资源(关文件、释放连接等),保证资源不泄漏。
defcheck_age(age):
ifage<0:
raiseValueError("年龄不能为负数")
returnage
raise 主动抛出异常。当你的函数收到非法参数时,主动 raise 一个异常,让调用方知道「这参数有问题」。
classNegativeMoneyError(Exception):
"""金额为负数时抛出。"""
pass
defcheck_money(m):
ifm<0:
raiseNegativeMoneyError("金额不能为负数")
returnm
自定义异常就是继承 Exception 建一个类。这样你的业务错误(如「金额不能为负」)也能用异常机制处理,语义更清晰。
把上面串起来,写一个「健壮的用户输入处理」小工具:
whileTrue:
try:
num=int(input("请输入一个整数:"))
exceptValueError:
print("输入的不是整数,请重新输入")
exceptKeyboardInterrupt:
print("\n用户中断,退出程序")
break
else:
print(f"你输入的是 {num},它的平方是 {num **2}")
break
这个例子:用户输入非数字会触发 ValueError,程序提示「重新输入」而不是崩溃;用户按 Ctrl+C 触发 KeyboardInterrupt,程序优雅退出。else 在输入合法时计算结果。一个典型的交互式程序的健壮写法。
别用裸 except:except: 不带类型会捕获所有异常(包括你想忽略的 KeyboardInterrupt、SystemExit),还会掩盖真正的 bug。永远写具体的异常类型。
except 顺序很重要:把具体的异常放前面,宽泛的(如 Exception)放后面。因为 Python 从上往下匹配,宽泛的放前面会「吞掉」后面所有的。
finally 代码块一定会执行:即使 try 里 return 或 break,finally 也会跑。所以清理资源的代码放 finally 最可靠。
异常有层级:所有异常都继承自 BaseException,常用的都继承自 Exception。自定义异常时继承 Exception(不要继承 BaseException,否则会误捕获系统级异常)。
① 能用 try/except 把 int("abc") 的报错兜住吗?
② 能用 except ValueError as e 拿到错误详情吗?
③ 能写出 else 和 finally 的分支吗?
④ 能定义一个自己的异常类,并在条件不满足时 raise 它吗?
这四题都能答上来,异常处理你就入门了。学会了它,你的程序就能从「一报错就崩溃」变成「出错也能优雅应对」,这是从玩具脚本走向正经程序的关键一步。
既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。
THANKS FOR READING