在 Python 开发的世界里,代码报错、程序突然终止,是每个开发者都曾遇到的 “噩梦现场”。这些运行时的错误,就是我们常说的异常(Exception)

今天,我们就从基础概念到进阶用法,再到自定义异常实战,把 Python 异常处理的知识点一次性讲透,帮你彻底告别 “程序一报错就崩” 的窘境。


一、什么是异常?

很多新手容易把 “编译错误” 和 “异常” 搞混,这里先做个清晰的区分:

  • 编译过程的错误:比如语法写错,IDE 会直接标红波浪线,代码根本无法运行,这不属于异常的范畴。
  • 运行过程的错误:代码语法没问题,能通过编译,但执行时出现了意外情况,比如分母为 0、文件不存在、类型转换失败,导致程序直接终止,这就是异常

Python 中所有异常的 “老祖宗” 是BaseException,我们日常处理的大部分业务异常,都继承自它的子类Exception。异常的核心特征就是:运行时触发错误信息,并直接终止程序流程。


二、基础异常处理:try-except 入门

处理异常最基础的语法就是try-except,它的核心逻辑很简单:把可能出错的代码放进try里,如果出错了,就执行except里的处理逻辑,而不是让程序直接崩溃

基础语法结构

3 个最常见的入门场景

我们用 3 个高频场景,带你快速上手基础用法:

场景 1:分母不能为 0(ZeroDivisionError)

  • 运行结果:程序不会直接崩溃,会先打印运行前,再打印错误信息这里出现错误 division by zero,最后正常执行运行后

场景 2:文件不存在(FileNotFoundError)

  • 这里我们精准指定了FileNotFoundError异常,比直接用Exception更精准,也更容易定位问题。

场景 3:类型转换失败(ValueError)

  • e.args是异常的参数元组,这里e.args[0]会直接输出错误信息的核心内容。

三、进阶异常处理:else + finally + 多异常捕获

基础的try-except只能处理 “出错了怎么办”,但实际开发中,我们还需要关注 “没出错时要做什么” 和 “无论出不出错都要执行的操作”,这就需要用到elsefinally

1. 完整的异常处理结构场景示例:文件读取的完整流程

  • lse:文件读取成功时执行,打印 “当前正常”。
  • finally:无论文件是否存在,都会执行,确保文件资源被正确释放。

2. 合并处理多个异常

如果一段代码可能触发多种异常,可以用元组把异常类型包起来,一次性处理:

3. 处理多级异常:从具体到通用

当需要区分不同异常的处理逻辑时,可以写多个except,但要遵循 “先具体,后通用”** 的原则:

注意:父类异常(比如Exception)要写在子类异常的后面,否则会提前捕获所有异常,导致后面的except永远不会执行。


四、自定义异常:用raise抛出自定义错误

Python 内置的异常虽然多,但业务场景千变万化,比如 “用户名不存在”“密码错误” 这类业务逻辑错误,内置异常无法直接表达,这时候就需要自定义异常

实现登录功能的自定义异常实战

我们通过一个登录场景,带你完整实现自定义异常:

运行效果

 


结语

异常处理不是 “万能补丁”,而是让程序更健壮的 “安全气囊”。从基础的try-exceptelse-finally,再到自定义异常,一步步掌握这些技巧,你就能写出 “报错不崩溃,错误可追溯” 的高质量 Python 代码。

  • 输入用户名lisi,密码123:触发MyException("用户名不存在"),程序打印错误信息。
  • 输入用户名zhangsan,密码456:触发MyException("密码错误"),程序打印错误信息。
  • 输入用户名zhangsan,密码123:没有异常,执行else里的print("ok")

    五、开发中处理异常的 3 个核心原则

  • 精准捕获,避免 “大而全”:优先捕获具体的异常类型(如FileNotFoundError),而不是直接用Exception,这样更容易定位问题。
  • 资源释放交给finally:文件、网络连接、数据库连接这类资源,一定要在finally中关闭,避免资源泄漏。
  • 业务错误用自定义异常:把业务逻辑错误和系统异常区分开,用自定义异常传递清晰的错误信息,让代码更易维护。

 

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐