DAY25 异常处理

部署运行你感兴趣的模型镜像

概览

  • 目标:系统掌握 Python 的异常处理模型(try / except / else / finally),理解其在工程实践(尤其是数据/模型训练与自动化流程)中的价值与用法。
  • 主线:异常对象与传播、语句结构设计、常见异常类型与定位、可恢复与不可恢复错误策略、资源清理与鲁棒性建设。

为什么要异常处理

  • 容错与稳定:运行时遇到意外并不直接崩溃,而是优雅处理、写入日志、释放资源、选择重试或降级。
  • 明确控制流:将“可能出错的核心逻辑”和“成功后的后续处理”分离,便于阅读与维护。
  • 工程契约:避免“隐藏错误”或“吞错”,为定位与恢复预留通道。

异常机制与对象

  • 异常发生时会创建异常对象(通常为 Exception 的子类),包含类型、消息与回溯。
  • 未被捕获的异常会沿调用栈向上传播(propagation),最终使程序崩溃并打印 traceback。
  • 设计要点:明确哪些错误应捕获、如何记录、是否可重试、是否需要释放资源。

基本结构

try-except

try:
    # 可能引发异常的代码
except SpecificError:   # 指定异常类型,如 ZeroDivisionError, FileNotFoundError
    # 补救或记录
except Exception:       # 非必要不建议:可能隐藏逻辑错误
    # 兜底处理(谨慎)
  • 作用:在风险代码出错时转入补救逻辑,程序不至于直接崩溃。
  • 建议:尽量“精确捕获”,避免一网打尽导致问题难以定位。

try-except-else

try:
    # 核心尝试逻辑(可能出错)
except SpecificError:
    # 异常处理
else:
    # 仅当 try 中无异常时执行的“成功后续逻辑”
  • 价值:避免把“成功后续处理”写进 try 中,导致其抛出的错误被误判为“核心逻辑错误”。
  • 工程建议:核心尝试逻辑尽量短小;成功后的扩展操作放到 else,保留“错误类型的清晰边界”。

finally(保证执行)

try:
    # 可能出错的操作
except SpecificError:
    # 处理错误
finally:
    # 无论是否出错都执行(资源清理、句柄关闭、状态恢复)
  • 用途:资源释放(文件/连接/锁)、还原全局状态、写入关键日志、持久化中断点。
  • with 的关系:with 管理协议本质上封装了类似 try-finally 的资源管理流程。

常见异常与定位思路

  • NameError:使用未定义的名称或打错变量名;先查作用域与拼写。
  • TypeError:操作与类型不匹配,如字符串与整数直连;检查类型并进行显式转换。
  • ValueError:类型正确但值非法,如将非数字字符串转为 int;校验输入值合理性。
  • AttributeError:访问对象不存在的属性或方法;确认 API 与属性拼写、对象真实类型。
  • ZeroDivisionError:除数为零;显式判断或保护性分支。
  • FileNotFoundError:路径不对或文件缺失;检查路径、工作目录与权限。
  • ModuleNotFoundError:模块未安装或导入名错误;确认包安装与导入路径。

定位技巧:阅读 traceback,关注“错误类型 + 文件/行号 + 代码片段”,从最内层调用点逆向分析。

多异常捕获与分层处理

try:
    # 读取 → 解析 → 计算 的复合流程
except (FileNotFoundError, PermissionError) as e:
    # I/O 层:路径或权限问题
except (ValueError, TypeError) as e:
    # 语义层:数据格式或类型问题
except Exception as e:
    # 兜底:记录未知异常,必要时上报/中止
else:
    # 成功路径:继续后续处理
finally:
    # 资源释放/日志
  • 分层思维:把“可预期的业务错误”与“系统性错误/未知错误”区分处理,便于定位与策略化响应。

示例:安全除法与后续扩展

def safe_divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        # 记录并给出可恢复返回值
        return None
    except TypeError:
        # 数据类型不符,提示并中止或转换
        return None
    else:
        # 仅在成功时运行的扩展逻辑
        return result

finally 在工程中的关键用法

  • 日志句柄/文件句柄关闭:避免数据丢失与文件损坏。
  • 计算资源释放:GPU/线程池/连接池归还。
  • 状态恢复:重置全局随机种子、环境变量、临时配置。
  • 中断点记录:长时训练失败时落盘当前状态,便于恢复。

注意:

  • 精确捕获:针对具体异常编写处理分支,减少吞错。
  • 简化 try:缩短 try 包裹范围,只含“可能抛错的核心操作”。
  • 记录与上报:日志包含错误类型、消息、堆栈;关键路径上报监控。
  • 失败即显式返回:返回 None/专用错误对象/Result 类型;避免继续用无效状态。
  • 不要无提示地 pass:最小化无内容的 except;至少记录。
  • 资源管理优先 with:文件/连接/锁尽量使用上下文管理器。
  • 重试策略:幂等操作可结合重试(指数退避)、降级或熔断。
  • 测试与注入:为关键分支写单元测试,必要时用“异常注入”验证鲁棒性。

示例:读取文件并解析数值

import os

def read_and_sum(path):
    try:
        with open(path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
    except FileNotFoundError:
        # 路径问题:记录并返回失败
        return None
    except PermissionError:
        # 权限问题
        return None
    except OSError:
        # 其他 I/O 问题
        return None
    else:
        total = 0
        for i, line in enumerate(lines, 1):
            try:
                total += float(line.strip())
            except ValueError:
                # 某行不可解析,记录并跳过或中止(视需求)
                continue
        return total

总结

  • 异常处理是将系统从“崩溃”提升到“可控”的核心机制:清晰边界、精确捕获、资源安全与可观测性。
  • try / except / else / finally 提供了表达这些工程约束的语法结构;配合日志、上下文管理与策略化重试,能显著提升系统鲁棒性。

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值