```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. 测试异常处理逻辑

```

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐