经历过模块化星系的探索([复习点这里]),是时候面对编程世界的终极挑战了——错误与异常!它们就像代码宇宙中的陨石雨:
-
语法错误 = 飞船设计图错误(根本飞不起来)
-
运行时异常 = 太空陨石袭击(飞行中突发危机)
-
逻辑错误 = 导航系统故障(悄悄飞向错误方向)
但别怕!Python的异常处理机制就是你的超级英雄救援队,随时准备化解危机拯救程序!穿上你的披风,我们出发!🦸♂️💥
一、为什么需要异常处理?程序崩溃的灾难现场 💥😱
想象你开发的太空点餐系统:
def order_food():
print("=== 太空餐厅点餐 ===")
food = input("请输入食物编号: ")
foods = ["🍔汉堡", "🍕披萨", "🌮塔可"]
# 致命漏洞:未处理无效输入!
selected = foods[int(food)-1]
print(f"已点餐: {selected}")
order_food()
灾难场景:·1
请输入食物编号: 4 # 输入不存在的编号
Traceback (most recent call last):
File "space.py", line 8, in <module>
order_food()
File "space.py", line 5, in order_food
selected = foods[int(food)-1]
IndexError: list index out of range
后果:
-
程序突然崩溃 → 宇航员饿肚子 😫
-
错误信息不友好 → 地面控制台混乱 🤯
-
未保存数据丢失 → 点餐记录消失 💾
💡 救援方案:异常处理机制——代码世界的能量护盾!🛡️
二、异常类型:认识你的敌人 🕵️♂️
Python有内置的异常"通缉名单":
常见异常罪犯:
# 1. 语法错误 - 连运行机会都没有!
# print("忘记关闭引号) # SyntaxError: EOL while scanning string literal
# 2. 名称错误 - 调用不存在的变量
# print(unknown_var) # NameError: name 'unknown_var' is not defined
# 3. 类型错误 - 错误的数据类型操作
# "100" + 50 # TypeError: can only concatenate str to str
# 4. 索引错误 - 访问不存在的索引
# foods = ["🍎", "🍌"]
# foods[2] # IndexError: list index out of range
# 5. 键错误 - 访问不存在的字典键
# menu = {"A1": "汉堡"}
# menu["B2"] # KeyError: 'B2'
# 6. 值错误 - 参数类型对但值非法
# int("abc") # ValueError: invalid literal for int()
异常家族谱系:
BaseException
├── SystemExit
├── KeyboardInterrupt # Ctrl+C触发
└── Exception
├── SyntaxError # 语法错误
├── NameError # 未定义变量
├── TypeError # 类型错误
├── IndexError # 索引越界
├── KeyError # 字典键不存在
├── ValueError # 值不合法
├── ZeroDivisionError # 除零错误
└── ... 其他40+异常
三、救援装备:try-except 防护盾 🛡️
基础救援语法:
try:
# 尝试执行危险代码
太空飞船.起飞()
except 异常类型 as 错误信息:
# 捕获到异常时的处理
紧急救援队.出动(错误信息)
实战:强化太空点餐系统
def safe_order_food():
print("=== 安全版太空餐厅 ===")
try:
food = input("请输入食物编号: ")
foods = ["🍔汉堡", "🍕披萨", "🌮塔可"]
selected = foods[int(food)-1] # 危险代码!
print(f"已点餐: {selected}")
except IndexError: # 捕获索引错误
print("⚠️ 警告:无效编号!请选择1-3")
except ValueError: # 捕获值转换错误
print("⚠️ 警告:请输入数字!")
except Exception as e: # 捕获其他所有异常
print(f"🆘 未知错误: {e}")
# 发送错误报告给地球
with open("error_log.txt", "a") as f:
f.write(f"点餐错误: {e}\n")
safe_order_food()
防护效果:
请输入食物编号: two
⚠️ 警告:请输入数字!
请输入食物编号: 4
⚠️ 警告:无效编号!请选择1-3
四、高级装备:else 和 finally 救援工具 🧰
1. else 区域:未发生异常时的奖励
try:
print("尝试连接太空站...")
connect_to_station()
except ConnectionError:
print("⚠️ 连接失败!启用备用方案")
else:
# 仅在try成功时执行
print("✅ 连接成功!开始传输数据")
transmit_data()
2. finally 区域:无论如何都要执行的清理任务
try:
print("打开太空舱外门...")
open_airlock()
perform_spacewalk() # 危险操作!
except SpaceSuitLeak:
print("🆘 宇航服泄露!紧急返回")
except MeteorShower:
print("☄️ 陨石雨!寻找掩护")
finally:
# 无论是否异常都执行
print("关闭并检查舱门...")
close_airlock()
check_seal() # 确保舱门密封
💡 黄金法则:finally 最适合资源清理(关闭文件、断开连接等)
五、主动出击:raise 发射警报 🚨
有时你需要主动引发异常:
def set_course(destination):
allowed = ["月球", "火星", "空间站"]
if destination not in allowed:
# 主动引发值错误
raise ValueError(f"禁止目的地: {destination}!只允许{allowed}")
print(f"航线设定: 前往{destination}")
# 使用示例
try:
set_course("金星")
except ValueError as e:
print(f"导航错误: {e}")
输出:
导航错误: 禁止目的地: 金星!只允许['月球', '火星', '空间站']
六、自定义异常:打造专属警报系统 🚧
当内置异常不够用时,创建你自己的异常类:
class FuelError(Exception):
"""燃料不足异常"""
def __init__(self, current, needed):
super().__init__(f"燃料不足!当前: {current}L, 需要: {needed}L")
self.current = current
self.needed = needed
# 使用自定义异常
def launch_rocket(fuel):
if fuel < 5000:
raise FuelError(fuel, 5000)
print("🚀 火箭发射成功!")
# 测试
try:
launch_rocket(3000)
except FuelError as e:
print(f"🆘 发射中止: {e}")
# 调用紧急燃料补给
emergency_refuel(e.needed - e.current)
七、异常处理最佳实践:英雄守则 📜
1.精准捕获:避免笼统的except Exception
# 不推荐
try:
risky_operation()
except: # 捕获所有异常,包括KeyboardInterrupt
print("发生错误")
# 推荐
try:
risky_operation()
except (SpecificError1, SpecificError2) as e:
handle_error(e)
2.保留原始异常信息
try:
connect_database()
except DatabaseError as e:
# 添加额外信息但保留原始异常
raise ConnectionFailed("数据库连接失败") from e
3.异常不是流程控制:避免用异常处理正常逻辑
# 反模式
try:
value = my_dict[key]
except KeyError:
value = default_value
# 正确做法
value = my_dict.get(key, default_value)
4.日志记录:使用logging模块记录异常
import logging
try:
critical_operation()
except Exception as e:
logging.error("操作失败", exc_info=True)
# 同时显示给用户友好信息
show_message("系统繁忙,请稍后再试")
八、闯关任务:太空堡垒防御系统 🛸🎯
任务要求:
-
创建防御系统类
DefenseSystem -
实现方法:
-
load_weapon(weapon_type):加载武器(可能引发InvalidWeaponError) -
fire():开火(可能引发AmmoError) -
recharge():充能
-
-
主程序使用异常处理保护系统
自定义异常:
class InvalidWeaponError(Exception):
"""无效武器异常"""
class AmmoError(Exception):
"""弹药不足异常"""
防御系统实现:
class DefenseSystem:
def __init__(self):
self.weapon = None
self.ammo = 0
def load_weapon(self, weapon_type):
valid_weapons = ["激光炮", "导弹", "电磁炮"]
if weapon_type not in valid_weapons:
raise InvalidWeaponError(f"无效武器: {weapon_type}!可选: {valid_weapons}")
self.weapon = weapon_type
print(f"🔫 已加载: {weapon_type}")
def fire(self):
if not self.weapon:
raise InvalidWeaponError("未加载武器!")
if self.ammo <= 0:
raise AmmoError("弹药不足!")
self.ammo -= 1
print(f"💥 使用{self.weapon}开火!剩余弹药: {self.ammo}")
def recharge(self, amount=10):
if amount <= 0:
raise ValueError("充能量必须为正数")
self.ammo += amount
print(f"⚡ 充能完成!当前弹药: {self.ammo}")
主程序:
def main():
shield = DefenseSystem()
while True:
try:
cmd = input("\n命令(load/fire/recharge/quit): ").strip().lower()
if cmd == "quit":
print("🛡️ 防御系统关闭")
break
elif cmd == "load":
weapon = input("输入武器类型: ")
shield.load_weapon(weapon)
elif cmd == "fire":
shield.fire()
elif cmd == "recharge":
try:
amount = int(input("充能量: "))
shield.recharge(amount)
except ValueError:
print("⚠️ 请输入有效数字!")
else:
print("未知命令!")
except (InvalidWeaponError, AmmoError) as e:
print(f"🆘 系统警报: {e}")
except Exception as e:
print(f"⛔ 未知系统故障: {e}")
# 紧急日志记录
with open("defense.log", "a") as f:
f.write(f"严重错误: {e}\n")
finally:
print("系统状态检测完成")
if __name__ == "__main__":
main()
异常处理超级英雄的装备清单 🦸♂️💼
-
try-except - 基础防护盾
-
else - 成功奖励区
-
finally - 终极清理区
-
raise - 主动警报器
-
自定义异常 - 专属警报系统
-
logging模块 - 战地记录仪
掌握了异常处理,你的代码将获得:
✅ 健壮性 - 抵御意外输入和故障
✅ 用户体验 - 友好提示替代崩溃
✅ 可维护性 - 错误定位和修复更快
✅ 安全性 - 资源泄漏风险大幅降低
现在就去打造你的不崩溃程序吧!宇宙需要你的守护! 🌌🦸♂️
418

被折叠的 条评论
为什么被折叠?



