news 2026/9/20 7:38:20

【Python】基础语法入门(二十一)——错误与异常处理:写出健壮可靠的程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Python】基础语法入门(二十一)——错误与异常处理:写出健壮可靠的程序


🛡️说明:没有程序能永远不出错。网络中断、文件丢失、用户输入非法……这些“意外”是常态。本篇系统讲解 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 应用!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 23:42:01

MudBlazor数据表格过滤功能深度解析与实战指南

MudBlazor数据表格过滤功能深度解析与实战指南 【免费下载链接】MudBlazor Blazor Component Library based on Material design with an emphasis on ease of use. Mainly written in C# with Javascript kept to a bare minimum it empowers .NET developers to easily debug…

作者头像 李华
网站建设 2026/9/19 5:51:48

Vico:重新定义Android数据可视化的全能图表库

Vico:重新定义Android数据可视化的全能图表库 【免费下载链接】vico A light and extensible chart library for Android. 项目地址: https://gitcode.com/gh_mirrors/vi/vico 在当今数据驱动的移动应用开发中,如何优雅地呈现复杂数据成为每个And…

作者头像 李华
网站建设 2026/9/19 14:52:10

35、利用 BAM 进行 SOA 指标监控

利用 BAM 进行 SOA 指标监控 1. SOA 指标类型 在面向服务的企业中,指标可以在不同级别进行收集。常见的指标类型与 SOA 类型的对应关系如下: | 指标类型 | 适用架构 | 说明 | | ---- | ---- | ---- | | 基础设施指标 | 服务库存架构 | 关注服务器的运行状况,如服务器的…

作者头像 李华
网站建设 2026/9/20 5:55:56

屏蔽机房:你不可忽视的物理层安全防线

在网络安全日益受到重视的今天,大多数人的关注点集中在防火墙、加密算法、零信任架构等“软件层面”的防护措施。然而,在高安全等级场景中,物理层的安全同样至关重要——其中,屏蔽机房(Electromagnetic Shielded Room&…

作者头像 李华
网站建设 2026/9/17 16:46:08

UI-TARS:70亿参数如何实现GUI交互的认知革命?

UI-TARS:70亿参数如何实现GUI交互的认知革命? 【免费下载链接】UI-TARS-7B-DPO 项目地址: https://ai.gitcode.com/hf_mirrors/ByteDance-Seed/UI-TARS-7B-DPO 在企业数字化进程中,每天都有数以万计的员工重复着相同的GUI操作&#x…

作者头像 李华
网站建设 2026/9/19 17:01:21

38、SOA设计模式参考指南

SOA设计模式参考指南 在面向服务架构(SOA)的设计中,有许多实用的设计模式可以帮助我们解决各种实际问题。下面将为大家详细介绍一系列SOA设计模式,包括它们所解决的问题、解决方案、应用场景、影响以及相关原则和架构。 1. 模式概述 模式的描述通常包含以下几个关键部分…

作者头像 李华