Python异常处理完整指南:Try-Except捕获、自定义异常与Finally应用

星野
星野
发布时间:2026-10-12| 2人浏览过
原创

在代码规模扩大后,不可预知的运行错误会直接导致服务中断。本文聚焦Python异常处理的核心机制,从try-except基础结构、多分支捕获规则,到raise主动触发、finally强制清理及自定义异常设计,提供标准化操作步骤与可运行代码,帮助开发者快速构建具备高容错能力的业务流程。

异常与语法错误的区别

代码执行受阻通常分为两类:语法错误(syntax error)与异常(exception)。语法错误指代码未遵循Python语言规范(如关键字混用、括号不匹配、缩进混乱),解释器在词法与语法解析阶段直接拦截,程序无法启动。异常则发生在合法代码的执行期,因数据越界、资源缺失或逻辑冲突触发。合理设计异常捕获能够阻断级联崩溃,显著降低运维成本。

核心操作:Try-Except 捕获机制

第1步:配置基础捕获结构

目的:拦截特定运行期错误,防止程序意外终止。
入口:任意包含高风险操作的函数或脚本模块。
动作:将易报错的代码段包裹在 try 块内,在其正下方对齐书写 except 异常类型: 分支。
重要参数:需准确填写目标异常类名(如 ZeroDivisionError、KeyError)。
完成状态:触发指定条件时控制台打印预设提示,主程序恢复正常运行。

def safe_division(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        print("错误:0 不能作为除数")

第2步:配置多分支与泛型捕获

目的:针对不同错误类型返回差异化响应,并设置最终兜底方案。
入口:同一 try 块下方依次追加 except 分支。
动作:使用元组 (Err1, Err2) 绑定通用逻辑;若需获取原始报错信息,搭配 as err_obj 映射变量。最后一支建议使用裸 except Exception: 拦截未预料异常。
重要参数:异常列表按精准度排列,父类严禁排在子类前方。
完成状态:不同错误触发对应分支,无遗漏时报错详情清晰输出。

def validate_data(raw_input):
    try:
        num = int(raw_input)
        result = 100 / num
        print(result)
    except (ValueError, TypeError) as err:
        print(f"数据格式不合法: {err}")
    except ZeroDivisionError as err:
        print(f"数学运算限制: {err}")
    except Exception as err:
        print(f"未预期系统异常: {err}")

第3步:利用 Else 处理无异常分支

目的:在 try 块彻底成功时执行后续业务,缩小异常监听作用域。
入口:except 分支全部声明完毕后,紧接着插入 else。
动作:将依赖前序步骤成功的逻辑(如数据解析、状态流转)移入 else。
完成状态:仅当 try 未抛异常时执行 else;若中途报错,直接跳过 else 进入 finally。

import os

try:
    handle = open("app_config.yml", "r")
    content = handle.read()
except FileNotFoundError:
    print("目标文件不存在")
else:
    print("文件读取成功,开始解析配置项")
    handle.close()

进阶控制:Raise、Finally 与自定义异常

第4步:使用 Raise 主动抛出异常

目的:在业务校验失败时,人为中断当前链路并向上层传递明确错误码。
入口:条件判断语句内部或工具函数头部。
动作:调用 raise 异常类(附加信息) 实例化对象。
重要参数:建议使用内置异常类或前述自定义异常类,附加描述性字符串便于排查。
完成状态:程序流立即跳出当前作用域,沿调用栈向上传递直至被 except 捕获或引发崩溃。

def check_access_level(level):
    if level < 2:
        raise PermissionError("权限不足,需要二级以上管理员")
    return "访问已通过"

第5步:添加 Finally 确保清理执行

目的:无论 try/except/else 执行路径如何,均强制回收资源。
入口:else 或末支 except 之后。
动作:写入资源释放代码(如 conn.close()、lock.release())。
完成状态:控制台显示清理日志,内存与句柄恢复正常,不影响上层返回值。

import sqlite3

def fetch_users():
    conn = None
    try:
        conn = sqlite3.connect("data.db")
        cursor = conn.cursor()
        return cursor.fetchall()
    except sqlite3.DatabaseError as e:
        print(f"数据库交互中断: {e}")
    finally:
        if conn:
            conn.close()
            print("数据库连接已强制释放")

第6步:定义并继承自定义异常类

目的:当内置异常无法满足业务分类需求时,建立专属错误标识体系。
入口:新建独立模块或脚本顶部初始化区域。
动作:自定义类必须直接或间接继承自 Exception。通常重写 __init__ 接收业务上下文参数,并通过 super() 传递消息基类。
完成状态:可通过 raise CustomErr(params) 触发,且能被 except Exception 统一捕获。

class BaseAppError(Exception):
    """应用层基础异常类"""
    pass

class PaymentTimeout(BaseAppError):
    """支付超时异常"""
    def __init__(self, order_id, timeout_sec):
        self.order_id = order_id
        self.timeout_sec = timeout_sec
        super().__init__(f"订单 {order_id} 支付等待超时 ({timeout_sec}s)")

注意事项:异常类的继承顺序

多层 except 的匹配严格自上而下。若父类异常写在子类之前,Python 会直接由父类承接,导致子类分支永远不可达。正确架构应将范围最广的父类(如 Exception)置于末尾,精确子类置顶。该原则同样适用于嵌套调用链中的异常传播方向。

总结

掌握 try-except 的分层结构与执行流向,配合 raise 规范业务边界、finally 保障底层资源回收,以及严谨的自定义异常设计,是构建高可用 Python 系统的核心能力。实际工程中应避免使用裸捕获掩盖关键堆栈,始终保留完整的错误溯源通道。以上就是Python异常处理完整指南的详细内容,更多关于Python基础编程技巧的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。