查看: 254|回复: 0

Python异常处理实践:try-except与自定义异常

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在Python项目里,运行时错误几乎无法避免:用户输入不合法、文件不存在、网络中断、除数为0,都可能让程序直接中断。异常处理机制的价值不在于彻底消灭错误,而在于错误发生时能识别问题、给出兜底逻辑、释放已占资源,让程序继续稳定运行。本文围绕语法错误与异常的区别、try-except捕获、异常信息获取、else与finally、raise与assert、自定义异常以及with上下文管理器,梳理一套可以直接落到代码里的处理思路。

【一、语法错误与异常:发生阶段不同】

Python中的错误主要分两类,虽然都会导致程序无法正常执行,但出现的阶段完全不同。

语法错误(Syntax Error)指代码不符合Python语法规则,在解析阶段就被解释器发现。这时程序还没有开始运行,必须修改代码才能执行。例如if条件后漏写冒号:
  1. if a == 1
  2.     print(a)
复制代码

运行结果为SyntaxError: expected ':'。常见的语法错误包括少写冒号、引号没有闭合、缩进错误、关键字拼写错误等。

异常(Exception)则是语法正确、程序可以运行,但在执行过程中发生错误。例如访问不存在的列表索引:
  1. lst = [1, 2, 3]
  2. print(lst[3])
复制代码

列表只有索引0、1、2,访问索引3会触发IndexError: list index out of range。

区分这两者的意义在于:语法错误只能在编码阶段修正,异常则可以在运行阶段被捕获和处理。

【二、try-except基本结构与执行流程】

最基础的异常处理结构是try-except:
  1. try:
  2.     # 可能发生异常的代码
  3. except:
  4.     # 异常处理代码
复制代码

它的执行流程分两种情况:

1. try代码块没有异常:执行完try后跳过except,继续往下执行。
2. try代码块发生异常:中断try中剩余代码,转入except执行,然后继续执行后面的程序。

示例:
  1. try:
  2.     result = 10 / 0
  3. except:
  4.     print("程序出现异常")
  5. print("程序继续执行")
复制代码

输出为:

程序出现异常
程序继续执行

可以看到,程序没有因为除零错误而整体崩溃。

【三、精准捕获与获取异常信息】

只写except:虽然简单,但它会捕获所有类型的异常,容易把不该吞掉的错误也一并隐藏。实际开发中更推荐精准捕获指定异常:
  1. try:
  2.     num = 10 / 0
  3. except ZeroDivisionError:
  4.     print("不能除以0")
复制代码

如果还需要拿到异常对象本身的信息,可以使用as e:
  1. try:
  2.     print(10 / 0)
  3. except ZeroDivisionError as e:
  4.     print(e)
复制代码

输出为division by zero。这样既知道异常类型,也能把具体错误信息记录到日志中。

【四、多异常处理与匹配顺序】

同一段代码可能抛出不同异常,可以写多个except分支:
  1. try:
  2.     a = int(input())
  3. except ValueError:
  4.     print("输入不是数字")
  5. except TypeError:
  6.     print("类型错误")
复制代码

Python会按except的书写顺序依次匹配,命中一个后就不再继续匹配。因此有一个重要原则:通配的except:必须放在最后,否则它会提前捕获所有异常,后面的分支永远不会执行。

【五、else:try成功时执行】

try-except还可以带一个可选的else子句,作用是:try代码块没有发生异常时执行。
  1. try:
  2.     result = 10 / 2
  3. except:
  4.     print("错误")
  5. else:
  6.     print(result)
复制代码

输出为5。

else的价值在于让职责更清晰:try只放有风险的代码,except处理错误,else处理成功后的结果,避免把正常逻辑也塞进try里而被误捕获。

【六、finally:无论是否异常都会执行】

finally的特点是:不管try中是否发生异常,它都会执行。
  1. try:
  2.     # 业务代码
  3. except:
  4.     # 异常处理
  5. finally:
  6.     # 必须执行的清理代码
复制代码

典型用途是关闭文件、关闭数据库连接、释放锁以及清理其他资源。例如:
  1. try:
  2.     file = open("test.txt")
  3. finally:
  4.     file.close()
复制代码

需要留意的是,这种写法在open本身失败时,file并未成功赋值,finally中直接调用close会再次触发异常。后续章节的with写法可以更好地规避这类问题。

【七、raise主动抛出异常与assert断言】

除了Python自动抛出的异常,开发者也可以用raise主动制造异常,常用于参数校验、业务规则检查和数据验证:
  1. def login(password):
  2.     if password != "123456":
  3.         raise ValueError("密码错误")
  4. login("111")
复制代码

调用后抛出ValueError: 密码错误。

assert则用于判断程序是否满足预期条件,格式为assert 条件, 提示信息:
  1. age = 10
  2. assert age >= 18, "年龄不符合要求"
复制代码

条件不成立时会产生AssertionError。assert适合开发调试阶段检查程序逻辑,不适合当作正式的业务异常处理手段。

【八、自定义异常:让业务错误可读】

Python内置了ValueError、TypeError、IndexError等异常,但业务中还会遇到用户不存在、余额不足、权限不足这类场景,此时可以定义自己的异常类。自定义异常必须继承Exception:
  1. class UserError(Exception):
  2.     pass
复制代码

使用时可以直接在业务函数中抛出并捕获:
  1. class UserNotFoundError(Exception):
  2.     pass
  3. def find_user(name):
  4.     users = ["admin"]
  5.     if name not in users:
  6.         raise UserNotFoundError("用户不存在")
  7. try:
  8.     find_user("Tom")
  9. except UserNotFoundError as e:
  10.     print(e)
复制代码

自定义异常的意义是让错误类型与业务语义对应,调用方捕获时能一眼看出问题属于哪个环节。

【九、with上下文管理器:自动释放资源】

文件、数据库连接、网络连接等资源在使用后必须释放。传统写法需要手动close,一旦中途出现异常就可能漏掉释放动作。with可以自动管理资源生命周期:
  1. with open("a.txt") as f:
  2.     data = f.read()
复制代码

代码块结束时,Python会自动关闭文件。从机制上看,with等价于try加finally,但写法更简洁,也更不容易遗漏清理步骤。

【十、常见异常类型速查】

ValueError:值错误
TypeError:类型错误
NameError:变量不存在
IndexError:索引越界
KeyError:字典不存在指定键
ZeroDivisionError:除数为0
AttributeError:属性错误
FileNotFoundError:文件不存在
SyntaxError:语法错误

【十一、实际开发中的四条原则】

1. 不要随便捕获所有异常。不推荐写except: pass,这会把错误彻底隐藏,后期排查非常困难。
2. 精准捕获异常。优先写except ValueError,而不是笼统地except:。
3. 资源必须释放。使用with open(),或者用finally保证清理逻辑一定执行。
4. 自定义异常贴近业务。像PasswordError、UserNotFoundError、PermissionError这类命名,能让调用方更快理解错误含义。

【总结】

语法错误属于代码规则问题,异常属于运行过程问题;try-except负责捕获,except as负责取错误信息,else处理成功分支,finally负责资源释放,raise用于主动抛错,assert用于调试检查,自定义异常表达业务语义,with负责自动管理资源。掌握这套机制,是Python从写出可运行代码走向可维护工程代码的关键一步。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-10 12:35 , Processed in 0.024365 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部