【Python】基础语法入门(二十一)——错误与异常处理:写出健壮可靠的程序
2026/5/27 15:54:46 网站建设 项目流程


🛡️说明:没有程序能永远不出错。网络中断、文件丢失、用户输入非法……这些“意外”是常态。本篇系统讲解 Python 的异常处理机制,教你如何优雅地捕获、处理和预防错误,让程序在异常情况下依然稳定运行或安全退出

你将掌握:

  • 异常 vs 错误的区别
  • try...except...else...finally完整结构
  • 常见内置异常类型及应对策略
  • 自定义异常类
  • 最佳实践:何时捕获?何时抛出?

1. 为什么需要异常处理?

❌ 不处理异常的后果

# 用户输入非数字age=int(input("请输入年龄: "))# 输入 "abc" → 程序崩溃!# ValueError: invalid literal for int() with base 10: 'abc'

✅ 处理后的体验

whileTrue:try:age=int(input("请输入年龄: "))breakexceptValueError:print("❌ 年龄必须是数字,请重试!")

💡目标

  • 防止程序崩溃
  • 给用户清晰提示
  • 记录错误日志便于排查

2. 异常处理基本结构

完整语法

try:# 可能出错的代码risky_operation()exceptSpecificErrorase:# 处理特定异常handle_error(e)except(Error1,Error2)ase:# 处理多种异常handle_common_error(e)exceptExceptionase:# 捕获所有其他异常(慎用!)log_and_exit(e)else:# 无异常时执行(可选)print("操作成功!")finally:# 无论是否异常都执行(清理资源)cleanup()

🔑执行流程
try→ 若无异常 →elsefinally
try→ 若有异常 → 匹配exceptfinally


3. 常见内置异常类型速查

异常触发场景处理建议
ValueError值类型正确但值无效(如int("abc")校验输入格式
TypeError类型不匹配(如"a" + 1检查变量类型
FileNotFoundError文件不存在检查路径或创建默认文件
KeyError字典键不存在.get()或先检查in
IndexError列表索引越界检查长度或用try
ZeroDivisionError除零错误判断分母是否为零
PermissionError权限不足提示用户或换路径

示例:安全读取字典

data={"name":"Alice"}# ❌ 危险print(data["age"])# KeyError!# ✅ 安全方式1:使用 get()age=data.get("age","未知")# ✅ 安全方式2:异常处理try:age=data["age"]exceptKeyError:age="未知"

4. 捕获多个异常

方式一:分别处理

try:withopen("config.txt")asf:value=int(f.read())exceptFileNotFoundError:print("配置文件缺失,使用默认设置")value=42exceptValueError:print("配置文件格式错误,使用默认值")value=42

方式二:统一处理

try:result=risky_calculation()except(ValueError,TypeError,ZeroDivisionError)ase:print(f"计算失败:{e}")result=0

⚠️避免:裸露的except:(会捕获包括KeyboardInterrupt在内的所有异常)


5.elsefinally的妙用

else:仅当无异常时执行

try:num=int(input("输入数字: "))exceptValueError:print("无效输入")else:print(f"你输入了:{num}")# 只有成功转换才打印

finally:资源清理(关键!)

file=Nonetry:file=open("data.txt")process(file)exceptIOError:print("文件处理失败")finally:iffile:file.close()# 确保文件关闭# ✅ 更好的写法:用 with(自动调用 __exit__)withopen("data.txt")asfile:process(file)# 自动关闭,无需 finally

💡黄金法则
能用with的地方(文件、锁、网络连接),就不要手动写finally


6. 抛出异常:raise

主动触发异常,用于校验或中断流程。

基本用法

defdivide(a,b):ifb==0:raiseValueError("除数不能为零!")returna/b# 调用try:result=divide(10,0)exceptValueErrorase:print(e)# 除数不能为零!

重新抛出异常

try:risky_operation()exceptExceptionase:log_error(e)# 记录日志raise# 重新抛出原异常(保留 traceback)

7. 自定义异常类

当内置异常无法准确描述问题时,创建专属异常。

示例:用户管理系统

classUserNotFoundError(Exception):"""用户未找到"""def__init__(self,user_id):self.user_id=user_idsuper().__init__(f"用户 ID{user_id}不存在")classInvalidEmailError(Exception):"""邮箱格式无效"""pass# 使用defget_user(user_id):ifnotdb.exists(user_id):raiseUserNotFoundError(user_id)try:user=get_user(999)exceptUserNotFoundErrorase:print(f"❌{e}")# 输出:❌ 用户 ID 999 不存在

命名规范:以Error结尾(如ValidationError


8. 异常处理最佳实践

原则说明
具体优于宽泛优先捕获FileNotFoundError而非Exception
不要忽略异常至少记录日志(logging.exception()
快速失败发现无效状态立即抛出异常,而非继续执行
异常用于异常情况不要用异常控制正常流程(如循环终止)
文档化异常在函数 docstring 中说明可能抛出的异常

反例:用异常控制流程(低效且难读)

# ❌ 不要这样做!i=0whileTrue:try:item=my_list[i]process(item)i+=1exceptIndexError:break# 用异常判断结束# ✅ 正确做法foriteminmy_list:process(item)

9. 实战:安全文件读取函数

整合所学知识,编写一个健壮的文件读取工具:

importloggingfrompathlibimportPathdefsafe_read_file(filepath:str,encoding:str="utf-8")->str|None:""" 安全读取文本文件。 :param filepath: 文件路径 :param encoding: 文件编码 :return: 文件内容,失败时返回 None :raises: 不抛出异常,内部处理并记录日志 """path=Path(filepath)try:ifnotpath.exists():logging.warning(f"文件不存在:{filepath}")returnNonereturnpath.read_text(encoding=encoding)exceptPermissionError:logging.error(f"权限不足,无法读取:{filepath}")exceptUnicodeDecodeErrorase:logging.error(f"编码错误 ({encoding}):{filepath},{e}")exceptOSErrorase:logging.error(f"系统错误读取文件{filepath}:{e}")returnNone# 所有异常路径均返回 None

✅ 特点:

  • 不暴露异常给调用者
  • 详细日志便于调试
  • 明确返回值语义

10. 总结:异常处理心法

  1. 预见错误:思考“这段代码可能在哪出错?”
  2. 精准捕获:只捕获你能处理的异常
  3. 优雅降级:提供备选方案(如默认值、重试)
  4. 透明反馈:让用户知道发生了什么
  5. 保持简洁:不要过度防御,平衡健壮性与复杂度

🐍记住
“异常处理不是掩盖错误,而是管理不确定性。”
—— 专业开发者的核心素养


下一步练习

  1. 改造你的 To-Do List
    • 添加输入验证(任务标题不能为空)
    • 捕获无效任务 ID 并友好提示
  2. 编写一个除法计算器
    • 处理非数字输入、除零错误
    • 支持连续计算直到用户退出
  3. 阅读官方文档:Built-in Exceptions

💥真正的健壮,是在风暴中依然前行。
用异常处理为你的程序穿上铠甲!

继续构建可靠、用户友好的 Python 应用!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询