第7章:异常与对象(Exceptions and Objects)
一、导读
1.1 本章学习目标
第7章讲解 Python 的异常处理和高级对象特性。异常处理是编写健壮代码的关键。
1.2 为什么第七章如此重要
异常处理让程序能够优雅地应对错误。理解异常层次和最佳实践是专业 Python 开发者的必备技能。
1.3 核心问题引导
Python 的异常层次结构是什么?
如何正确使用 try/except?
自定义异常如何设计?
上下文管理器如何工作?
二、核心概念详解
7.1 异常层次
BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception
├── ArithmeticError
│ ├── ZeroDivisionError
│ └── OverflowError
├── AttributeError
├── ImportError
├── IndexError
├── KeyError
├── NameError
├── OSError
│ ├── FileNotFoundError
│ └── PermissionError
├── TypeError
└── ValueError7.2 异常处理最佳实践
python
# 只捕获特定异常
try:
result = 10 / value
except ZeroDivisionError:
print("Cannot divide by zero")
except TypeError as e:
print(f"Type error: {e}")
# 使用 else 和 finally
try:
f = open("file.txt")
except FileNotFoundError:
print("File not found")
else:
content = f.read() # 没有异常时执行
finally:
f.close() # 总是执行
# 不要捕获所有异常
# 反模式
try:
do_something()
except Exception: # 太宽泛
pass
# 正确做法
try:
do_something()
except SpecificError as e:
logger.error(f"Specific error: {e}")
raise7.3 自定义异常
python
class AppError(Exception):
"""应用基础异常"""
pass
class ValidationError(AppError):
"""验证错误"""
def __init__(self, field, message):
self.field = field
self.message = message
super().__init__(f"Validation error on '{field}': {message}")
class NotFoundError(AppError):
"""资源未找到"""
def __init__(self, resource, id):
self.resource = resource
self.id = id
super().__init__(f"{resource} with id '{id}' not found")
# 使用
try:
validate_user(data)
except ValidationError as e:
print(f"Invalid {e.field}: {e.message}")7.4 上下文管理器
python
# 使用 contextlib
from contextlib import contextmanager
@contextmanager
def timer(label):
start = time.time()
yield
elapsed = time.time() - start
print(f"{label}: {elapsed:.2f}s")
with timer("Operation"):
time.sleep(1)
# 管理多个资源
from contextlib import ExitStack
with ExitStack() as stack:
files = [stack.enter_context(open(f"f{i}.txt")) for i in range(5)]
# 所有文件自动关闭三、实战案例
7.1 异常链
python
class DatabaseError(AppError):
pass
class UserRepository:
def find_by_id(self, user_id):
try:
return self.db.query(f"SELECT * FROM users WHERE id = {user_id}")
except ConnectionError as e:
raise DatabaseError(f"Database connection failed") from e
except Exception as e:
raise DatabaseError(f"Query failed") from e
# 保留原始异常信息
try:
user = repo.find_by_id(123)
except DatabaseError as e:
print(f"Error: {e}")
print(f"Cause: {e.__cause__}")四、本章小结
Python 异常层次清晰。只捕获特定异常,使用异常链保留原始信息。自定义异常继承自 AppError。上下文管理器简化资源管理。
五、思考与练习
Python 的异常层次结构是什么?
如何正确使用 try/except/else/finally?
自定义异常如何设计?
异常链的作用是什么?
上下文管理器如何工作?