```python
# Python异常处理实用技巧
## 1. 基础异常处理结构
```python
try:
# 可能引发异常的代码
result = 10 / 0
except ZeroDivisionError as e:
# 处理特定异常
print(f除零错误: {e})
except Exception as e:
# 处理其他异常
print(f其他错误: {e})
else:
# 无异常时执行
print(计算成功)
finally:
# 无论是否异常都会执行
print(清理资源)
```
## 2. 自定义异常类
```python
class ValidationError(Exception):
自定义验证异常
def __init__(self, message, field=None):
self.message = message
self.field = field
super().__init__(self.message)
def validate_age(age):
if age < 0:
raise ValidationError(年龄不能为负数, age)
if age > 150:
raise ValidationError(年龄超出合理范围, age)
try:
validate_age(-5)
except ValidationError as e:
print(f验证失败: {e.message}, 字段: {e.field})
```
## 3. 上下文管理器处理资源
```python
from contextlib import contextmanager
@contextmanager
def database_connection(connection_string):
connection = None
try:
connection = connect(connection_string)
yield connection
except DatabaseError as e:
print(f数据库错误: {e})
raise
finally:
if connection:
connection.close()
# 使用示例
with database_connection(db://localhost) as conn:
conn.execute(SELECT FROM users)
```
## 4. 异常链与重新抛出
```python
def process_data(data):
try:
return int(data)
except ValueError as e:
raise ProcessingError(f数据处理失败: {data}) from e
class ProcessingError(Exception):
pass
try:
process_data(abc)
except ProcessingError as e:
print(f错误: {e})
print(f原始错误: {e.__cause__})
```
## 5. 使用断言进行调试
```python
def calculate_discount(price, discount_rate):
assert price >= 0, 价格不能为负数
assert 0 <= discount_rate <= 1, 折扣率必须在0-1之间
return price (1 - discount_rate)
# 在开发环境中检查,生产环境可通过-O参数禁用
try:
result = calculate_discount(-100, 0.1)
except AssertionError as e:
print(f断言失败: {e})
```
## 6. 日志记录异常
```python
import logging
logging.basicConfig(level=logging.ERROR)
def risky_operation():
try:
# 危险操作
risky_code()
except Exception as e:
logging.error(操作失败, exc_info=True)
# 记录完整堆栈跟踪
logging.exception(详细异常信息)
def risky_code():
raise ValueError(模拟错误)
```
## 7. 异常处理装饰器
```python
from functools import wraps
def handle_exceptions(default_return=None):
def decorator(func):
@wraps(func)
def wrapper(args, kwargs):
try:
return func(args, kwargs)
except Exception as e:
print(f函数 {func.__name__} 执行失败: {e})
return default_return
return wrapper
return decorator
@handle_exceptions(default_return=0)
def safe_divide(a, b):
return a / b
result = safe_divide(10, 0) # 返回0而不是崩溃
```
## 8. 批量操作中的异常处理
```python
def process_items(items):
successful = []
failed = []
for item in items:
try:
result = process_single_item(item)
successful.append(result)
except ProcessingError as e:
print(f处理项目 {item} 失败: {e})
failed.append(item)
except Exception as e:
print(f意外错误: {e})
failed.append(item)
return successful, failed
def process_single_item(item):
if item < 0:
raise ProcessingError(项目值不能为负数)
return item 2
```
## 9. 超时异常处理
```python
import signal
from contextlib import contextmanager
class TimeoutError(Exception):
pass
@contextmanager
def timeout(seconds):
def signal_handler(signum, frame):
raise TimeoutError(操作超时)
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0)
try:
with timeout(5):
# 可能长时间运行的操作
long_running_operation()
except TimeoutError as e:
print(f操作超时: {e})
```
## 10. 数据验证与异常处理结合
```python
from typing import Optional
def validate_and_process(data: dict) -> Optional[dict]:
required_fields = ['name', 'age', 'email']
try:
# 检查必需字段
for field in required_fields:
if field not in data:
raise ValidationError(f缺少必需字段: {field})
# 验证数据类型
if not isinstance(data['age'], int):
raise ValidationError(年龄必须是整数)
if data['age'] < 0:
raise ValidationError(年龄不能为负数)
# 处理数据
return {
'name': data['name'].strip(),
'age': data['age'],
'email': data['email'].lower()
}
except ValidationError as e:
print(f数据验证失败: {e})
return None
except Exception as e:
print(f处理过程中发生意外错误: {e})
return None
```
## 最佳实践总结
1. 具体异常捕获: 避免裸的except语句,捕获具体异常类型
2. 资源清理: 使用finally或上下文管理器确保资源释放
3. 异常信息丰富: 提供有意义的错误信息和上下文
4. 适当重新抛出: 在需要时重新抛出异常,保持调用栈
5. 日志记录: 记录异常信息便于调试和监控
6. 防御性编程: 使用断言和验证提前发现问题
7. 用户体验: 对最终用户显示友好的错误信息
这些技巧能帮助编写更健壮、可维护的Python代码,有效处理各种异常情况。
355

被折叠的 条评论
为什么被折叠?



