Python中高效处理异常情况的实用技巧
```python
# Python异常处理实用技巧
## 1. 基础异常处理结构
try:
# 可能引发异常的代码
result = 10 / 0
except ZeroDivisionError as e:
# 处理特定异常
print(f除零错误: {e})
except Exception as e:
# 处理其他异常
print(f其他错误: {e})
else:
# 无异常时执行
print(操作成功)
finally:
# 无论是否异常都会执行
print(清理操作)
## 2. 自定义异常类
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)
## 3. 上下文管理器处理资源
from contextlib import contextmanager
@contextmanager
def database_connection(connection_string):
conn = None
try:
conn = create_connection(connection_string)
yield conn
except DatabaseError as e:
print(f数据库错误: {e})
raise
finally:
if conn:
conn.close()
# 使用示例
with database_connection(db://localhost) as conn:
conn.execute_query(SELECT FROM users)
## 4. 异常链与重新抛出
def process_data(data):
try:
return complex_processing(data)
except ProcessingError as e:
# 添加额外信息并重新抛出
raise ProcessingError(f处理数据失败: {data}) from e
## 5. 使用logging记录异常
import logging
logging.basicConfig(level=logging.ERROR)
def safe_operation():
try:
risky_operation()
except Exception as e:
logging.exception(操作执行失败)
# 记录完整堆栈跟踪
## 6. 多重异常处理
try:
file_operation()
except (FileNotFoundError, PermissionError) as e:
print(f文件操作失败: {e})
except IOError as e:
if e.errno == 28:
print(磁盘空间不足)
else:
raise
## 7. 使用else块优化逻辑
def find_user(user_id):
try:
user = db.get_user(user_id)
except UserNotFound:
return None
else:
# 只有在没有异常时才执行
user.last_login = datetime.now()
return user
## 8. 异常处理的性能考虑
# 避免在循环中使用try/except
# 不推荐的写法
def slow_process(items):
results = []
for item in items:
try:
result = process(item)
results.append(result)
except ProcessingError:
continue
return results
# 推荐的写法
def fast_process(items):
results = []
for item in items:
if can_process(item): # 预先检查
result = process(item)
results.append(result)
return results
## 9. 使用functools.singledispatch处理不同类型异常
from functools import singledispatch
@singledispatch
def handle_error(exc):
默认异常处理器
logging.error(f未处理的异常: {exc})
@handle_error.register
def _(exc: ValueError):
处理ValueError
logging.warning(f值错误: {exc})
@handle_error.register
def _(exc: TypeError):
处理TypeError
logging.error(f类型错误: {exc})
## 10. 异步异常处理
import asyncio
async def async_operation():
try:
result = await some_async_call()
return result
except asyncio.TimeoutError:
print(操作超时)
except asyncio.CancelledError:
print(操作被取消)
raise # 必须重新抛出CancelledError
## 11. 使用断言进行调试
def calculate_discount(price, discount):
assert price > 0, 价格必须为正数
assert 0 <= discount <= 1, 折扣必须在0-1之间
return price (1 - discount)
## 12. 异常处理的测试
import unittest
from unittest.mock import patch
class TestExceptionHandling(unittest.TestCase):
def test_division_by_zero(self):
with self.assertRaises(ZeroDivisionError):
10 / 0
def test_custom_exception(self):
with self.assertRaises(ValidationError) as context:
validate_age(-1)
self.assertEqual(context.exception.field, age)
## 最佳实践总结
1. 具体异常优先于通用Exception
2. 避免空的except块
3. 合理使用异常链
4. 资源清理使用finally或上下文管理器
5. 记录有意义的错误信息
6. 不要用异常处理控制正常流程
7. 测试异常处理逻辑
```
更多推荐
所有评论(0)