核心梗概:程序运行就像开车,难免会爆胎(报错)。异常处理不是让车不爆胎,而是保证爆胎后你能稳稳停在应急车道,而不是冲下山崖。
1. 为什么你的程序总“闪退”?因为你没上保险!
很多新手写代码,最怕看见红字报错。其实报错不可怕,可怕的是不处理。用户输入"abc"而你非要int()转换,程序直接就“炸”了。我们的宗旨是:把“车祸现场”变成“交通管制”。
while True: try: # 高危操作区 num = int(input("给我一个数字,不然我死给你看:")) result = 100 / num print(f"结果是 {result}") # 针对性拦截:捕获特定的坏人 except ValueError: print("你输入的不是数字!请重新输入,我等你。") except ZeroDivisionError: print("数字 0 不能做除数!你想让我灰飞烟灭吗?重新来!") # 捕获所有其他未知的妖魔鬼怪(必须放最后) except Exception as e: print(f"遇到未知神秘力量干扰:{e},我要申请重启程序了。") break # 只有没出错才执行(彩票中奖区) else: print("耶!本次计算完美无瑕,你真是个小天才!") break # 正确了,退出循环 # 无论死活,都会执行(打扫战场) finally: print("本回合结束,无论成败,我都清理了战场(比如关闭文件)")2.else和finally的“宫斗戏”
很多同学分不清else和finally,其实很简单:
else是舔狗:只有当try里一切顺利(没抛异常),它才屁颠屁颠跑出来执行。finally是扫地阿姨:不管你try里是炸了(异常)还是跑了(return),它都雷打不动地执行,专门用来关文件、关数据库连接、关网络套接字。
3. 进阶大招:自己造“专属炸弹”(自定义异常)
业务逻辑复杂了,比如你规定 18 岁以下不能进网吧。Python 自带的异常不够贴切,我们就自己造一个异常类,让代码读起来像小说一样通顺。
# 继承 Exception,自定义一个业务异常 class UnderAgeError(Exception): """未成年自定义异常""" def __init__(self, age, message="未成年人禁止入内"): self.age = age self.message = message super().__init__(self.message) def enter_internet_bar(age): if age < 18: # 抛出自制的炸弹 raise UnderAgeError(age, f"年龄 {age} 太小了,回家写作业去!") else: print("欢迎光临,来一把紧张刺激的LOL吧!") # 捕获自己造的炸弹 try: enter_internet_bar(16) except UnderAgeError as e: print(f"网管拦截:{e}") # 网管拦截:年龄 16 太小了,回家写作业去!4. 高手进阶:异常链(raise ... from)
有时候我们在处理一个异常时,触发了另一个异常,这会掩盖原始的报错信息。Python 3 引入了异常链,让你能追根溯源:
try: with open("不存在的文件.txt") as f: content = f.read() except FileNotFoundError as e: # 抛出一个新的异常,但把旧的 e 作为“原因”带上去 raise RuntimeError("加载配置文件失败,系统即将崩溃") from e # 控制台会清晰地告诉你:上面是因为找不到文件,下面是因为加载失败。总结:异常处理是程序员最后的尊严。别让你的程序像个玻璃瓶,一摔就碎;要让它像个皮球,拍一下还能弹起来。用好try-except,就是给代码穿上了一层“软猬甲”!