目录
[1 异常处理基础概念](#1 异常处理基础概念)
[1.1 什么是异常?](#1.1 什么是异常?)
[1.2 异常与错误的区别](#1.2 异常与错误的区别)
[2 异常处理基础](#2 异常处理基础)
[2.1 常见内置异常类型](#2.1 常见内置异常类型)
[2.2 try-except 基本结构](#2.2 try-except 基本结构)
[2.3 捕获多个异常](#2.3 捕获多个异常)
[2.4 抛出异常](#2.4 抛出异常)
[2.4.1 使用raise语句](#2.4.1 使用raise语句)
[2.4.2 自定义异常类](#2.4.2 自定义异常类)
[3 高级异常处理技巧](#3 高级异常处理技巧)
[3.1 不要过度捕获异常](#3.1 不要过度捕获异常)
[3.2 使用上下文管理器(with语句)](#3.2 使用上下文管理器(with语句))
[3.3 记录异常信息](#3.3 记录异常信息)
[3.4 异常链(Exception Chaining)](#3.4 异常链(Exception Chaining))
[3.5 异常处理装饰器](#3.5 异常处理装饰器)
1 异常处理基础概念
1.1 什么是异常?
异常处理是Python编程中至关重要的部分,它帮助我们优雅地处理程序运行时可能出现的错误情况。
在Python中,异常 是指程序执行过程中发生的意外情况,它会中断正常的程序流程。当Python遇到无法正常处理的情况时,会**抛出(raise)**一个异常。
python
# 基本异常示例
try:
result = 10 / 0 # 这会引发ZeroDivisionError
except ZeroDivisionError:
print("不能除以零!")
1.2 异常与错误的区别
-
语法错误(Syntax Error):代码不符合Python语法规则,程序无法运行
-
异常(Exception):程序运行时发生的意外情况,可以被捕获和处理
2 异常处理基础
2.1 常见内置异常类型
异常类型 | 触发场景 |
---|---|
SyntaxError |
语法错误 |
IndentationError |
缩进错误 |
NameError |
访问未定义变量 |
TypeError |
类型操作不当 |
ValueError |
值无效或不合法 |
IndexError |
序列索引超出范围 |
KeyError |
字典键不存在 |
AttributeError |
对象没有该属性 |
IOError /OSError |
输入/输出操作失败 |
ImportError |
导入模块失败 |
ZeroDivisionError |
除数为零 |
FileNotFoundError |
文件不存在 |
2.2 try-except 基本结构
python
try:
# 可能引发异常的代码
result = 10 / 0
except ZeroDivisionError:
# 处理特定异常
print("不能除以零!")
except (TypeError, ValueError) as e:
# 处理多种异常
print(f"类型或值错误: {e}")
except Exception as e:
# 捕获所有其他异常
print(f"发生未知错误: {e}")
else:
# 没有异常发生时执行
print("一切正常!")
finally:
# 无论是否发生异常都会执行
print("清理工作完成")
2.3 捕获多个异常
python
try:
# 可能引发多种异常的代码
data = {"key": "value"}
print(data["missing_key"]) # 可能引发KeyError
print(10 / 0) # 可能引发ZeroDivisionError
except (KeyError, ZeroDivisionError) as e:
print(f"捕获到异常: {type(e).__name__}")
2.4 抛出异常
2.4.1 使用raise语句
python
def validate_age(age):
if age < 0:
raise ValueError("年龄不能为负数")
if age > 120:
raise ValueError("年龄不合理")
try:
validate_age(-5)
except ValueError as e:
print(f"验证失败: {e}")
2.4.2 自定义异常类
示例1:
python
class InvalidEmailError(Exception):
"""自定义异常类表示无效邮箱"""
def __init__(self, email, message="无效的邮箱地址"):
self.email = email
self.message = message
super().__init__(f"{message}: {email}")
def send_email(email):
if "@" not in email:
raise InvalidEmailError(email)
try:
send_email("invalid.email")
except InvalidEmailError as e:
print(e)
示例2:
python
class MyCustomError(Exception):
"""自定义异常类"""
def __init__(self, message, code):
super().__init__(message)
self.code = code
def validate_age(age):
if age < 0:
raise MyCustomError("年龄不能为负数", 400)
elif age > 120:
raise MyCustomError("年龄不现实", 400)
try:
validate_age(-5)
except MyCustomError as e:
print(f"错误代码 {e.code}: {e}")
3 高级异常处理技巧
3.1 不要过度捕获异常
python
# 不好的做法 - 捕获过于宽泛的异常
try:
do_something()
except:
pass
# 好的做法 - 只捕获预期的异常
try:
do_something()
except ExpectedError:
handle_error()
3.2 使用上下文管理器(with语句)
python
# 自动处理资源释放
try:
with open("data.txt", "r") as f:
content = f.read()
except IOError as e:
print(f"文件操作失败: {e}")
3.3 记录异常信息
python
import logging
logging.basicConfig(filename="app.log", level=logging.ERROR)
def critical_operation():
try:
1 / 0
except Exception as e:
logging.exception("操作失败") # 记录完整堆栈跟踪
raise # 重新抛出异常
try:
critical_operation()
except Exception:
print("操作失败,请查看日志")
3.4 异常链(Exception Chaining)
python
try:
# 原始异常
raise ValueError("原始错误")
except ValueError as ve:
try:
# 处理时引发新异常
raise RuntimeError("处理错误") from ve
except RuntimeError as re:
print(f"当前异常: {re}")
print(f"原始异常: {re.__cause__}")
3.5 异常处理装饰器
python
from functools import wraps
def handle_errors(logger):
"""异常处理装饰器工厂"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
logger.error(f"{func.__name__} 失败: {e}")
raise
return wrapper
return decorator
# 使用装饰器
import logging
logger = logging.getLogger(__name__)
@handle_errors(logger)
def risky_operation():
"""可能失败的操作"""
raise ValueError("出错了!")
try:
risky_operation()
except ValueError:
print("操作失败已处理")
注意,良好的异常处理策略应该:
-
只捕获能处理的异常
-
保留原始异常信息
-
提供有意义的错误消息
-
适当记录错误日志
-
在适当的时候重新抛出异常
如果您觉得本文章对您有帮助,别忘了点赞、收藏加关注,更多干货内容将持续发布,您的支持就是作者更新最大的动力。本专栏将持续更新,有任何问题都可以在评论区讨论