python exception
Python 异常 (Exception) 是指程序在运行过程中遇到的“意外状况”或错误。当 Python 解释器检测到无法处理的情况时,会中断正常的代码执行流程并抛出一个异常对象。如果不对异常进行处理,程序将会崩溃并显示错误信息(Traceback)。
通过异常处理机制,开发者可以捕获这些错误,执行特定的补救措施(如记录日志、提示用户、清理资源),从而避免程序直接崩溃,提高软件的健壮性。
1. 核心概念与分类
Python 中的错误主要分为两类:
- 语法错误 (SyntaxError):代码不符合 Python 语法规则(如缺少冒号、括号不匹配)。这类错误在代码运行前由解析器发现,无法通过
try-except捕获。 - 异常 (Exception):代码语法正确,但在运行时发生错误(如除以零、文件不存在)。这类错误可以通过
try-except进行捕获和处理。
常见内置异常类型
表格
| 异常名称 | 描述 | 示例场景 |
|---|---|---|
SyntaxError |
语法错误 | if True print("hi") (缺少冒号) |
NameError |
变量未定义 | 使用了一个从未赋值的变量 print(x) |
TypeError |
类型错误 | 对字符串和整数进行加法运算 "a" + 1 |
ValueError |
值错误 | 将非数字字符串转换为整数 int("abc") |
ZeroDivisionError |
除零错误 | 10 / 0 |
FileNotFoundError |
文件未找到 | 打开一个不存在的路径 open("no_file.txt") |
IndexError |
索引越界 | 访问列表超出范围的索引 lst (列表长度不足) |
KeyError |
键不存在 | 访问字典中不存在的键 d["missing_key"] |
AttributeError |
属性/方法不存在 | 调用对象没有的方法 123.append(1) |
2. 异常处理基本结构
Python使用 try、except、else 和 finally 关键字来构建异常处理逻辑。
python
try: # 1. 可能抛出异常的代码块 result = 10 / 0 except ZeroDivisionError as e: # 2. 捕获特定异常并处理 print(f"捕获到除零错误: {e}") except (TypeError, ValueError) as e: # 3. 同时捕获多种异常 print(f"类型或数值错误: {e}") except Exception as e: # 4. 捕获所有其他非系统退出类异常(通用兜底) print(f"未知错误: {e}") else: # 5. 如果没有发生异常,则执行此块 print("计算成功,结果是:", result) finally: # 6. 无论是否发生异常,最终都会执行此块(常用于资源清理) print("执行清理工作") 关键要点:
- 精确捕获:尽量捕获具体的异常类型(如
ValueError),避免滥用通用的except Exception,否则可能会掩盖潜在的 Bug。 - as 子句:使用
as e可以将异常对象赋值给变量,以便获取详细的错误信息。 - else 块:仅在没有异常发生时执行,适合放置依赖 try 块成功执行后的逻辑。
- finally 块:始终执行,适合关闭文件、断开数据库连接等收尾工作。
3. 主动抛出与自定义异常
手动抛出异常 (raise)
当程序遇到不符合业务逻辑的情况时,可以主动抛出异常。
python
def set_age(age): if age < 0: raise ValueError("年龄不能为负数") return age try: set_age(-5) except ValueError as e: print(e) # 输出: 年龄不能为负数 异常链 (raise ... from ...)
在处理异常时,如果需要抛出新的异常但保留原始错误的上下文,可以使用 from 关键字。
python
try: import non_existent_module except ImportError as ie: raise RuntimeError("模块加载失败") from ie 自定义异常
通过继承 Exception 类,可以创建符合特定业务需求的异常类型。
python
class InsufficientBalanceError(Exception): """余额不足异常""" def __init__(self, message, balance): super().__init__(message) self.balance = balance # 使用 try: raise InsufficientBalanceError("余额不足", 0) except InsufficientBalanceError as e: print(f"错误: {e}, 当前余额: {e.balance}") 4. 最佳实践
- 不要静默忽略异常:空的
except:块会吞掉所有错误,导致调试极其困难。至少应记录日志。 - 优先使用内置异常:除非有特殊的业务含义,否则尽量使用 Python 内置的标准异常类型。
- 资源管理使用
with语句:对于文件操作、数据库连接等,推荐使用上下文管理器(with语句),它会自动处理异常时的资源清理,比手动写finally更简洁安全。 - 记录详细日志:在生产环境中,捕获异常时应使用
logging模块记录完整的 traceback 信息,便于后续排查问题。
漫思
浙公网安备 33010602011771号