本文目录导读:

我来详细讲解Python中捕获异常的多种方法和实践案例。
基础异常捕获结构
try-except 基础用法
# 基础捕获
try:
result = 10 / 0
except ZeroDivisionError:
print("除数不能为零!")
# 捕获多个异常
try:
num = int(input("请输入数字:"))
result = 10 / num
except ValueError:
print("请输入有效的数字!")
except ZeroDivisionError:
print("除数不能为零!")
# 捕获所有异常(不推荐,应尽量精确)
try:
# 一些操作
pass
except Exception as e:
print(f"发生错误:{e}")
实际应用案例
案例1:文件操作异常处理
def read_file(filename):
"""安全读取文件"""
try:
with open(filename, 'r', encoding='utf-8') as file:
content = file.read()
return content
except FileNotFoundError:
print(f"错误:文件 '{filename}' 不存在")
return None
except PermissionError:
print(f"错误:没有权限读取文件 '{filename}'")
return None
except Exception as e:
print(f"读取文件时发生未知错误:{e}")
return None
# 使用示例
content = read_file("data.txt")
if content:
print("文件内容:", content[:100])
案例2:网络请求异常处理
import requests
from requests.exceptions import RequestException, Timeout, ConnectionError
def fetch_data(url, timeout=5):
"""安全获取网络数据"""
try:
response = requests.get(url, timeout=timeout)
response.raise_for_status() # 检查HTTP状态码
return response.json()
except Timeout:
print(f"错误:请求超时({timeout}秒)")
return None
except ConnectionError:
print(f"错误:无法连接到 {url}")
return None
except RequestException as e:
print(f"网络请求错误:{e}")
return None
except ValueError as e:
print(f"JSON解析错误:{e}")
return None
# 使用示例
data = fetch_data("https://api.example.com/data")
if data:
print("获取的数据:", data)
案例3:数据库操作异常处理
import sqlite3
from sqlite3 import Error as SQLError
class DatabaseManager:
def __init__(self, db_path):
self.db_path = db_path
self.connection = None
def connect(self):
"""安全连接数据库"""
try:
self.connection = sqlite3.connect(self.db_path)
print("数据库连接成功")
return True
except SQLError as e:
print(f"数据库连接失败:{e}")
return False
def execute_query(self, query, params=None):
"""安全执行SQL查询"""
try:
cursor = self.connection.cursor()
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
self.connection.commit()
return cursor.fetchall()
except SQLError as e:
print(f"SQL执行错误:{e}")
self.connection.rollback()
return None
except AttributeError as e:
print(f"数据库未连接:{e}")
return None
def close(self):
"""安全关闭连接"""
try:
if self.connection:
self.connection.close()
print("数据库连接已关闭")
except SQLError as e:
print(f"关闭连接时出错:{e}")
# 使用示例
db = DatabaseManager("test.db")
if db.connect():
result = db.execute_query("SELECT * FROM users")
if result:
for row in result:
print(row)
db.close()
高级异常处理技巧
完整的异常处理结构
def advanced_error_handling():
"""演示完整的异常处理结构"""
try:
# 尝试执行的代码
print("正在执行操作...")
x = int(input("请输入数字:"))
result = 100 / x
print(f"结果:{result}")
except ValueError:
# 处理特定异常
print("请输入有效数字!")
except ZeroDivisionError:
# 处理除零异常
print("除数不能为零!")
except Exception as e:
# 处理其他所有异常
print(f"未知错误:{type(e).__name__}: {e}")
else:
# 没有异常时执行
print("操作成功完成!")
finally:
# 无论是否有异常都会执行
print("清理工作:关闭资源等")
# 运行示例
advanced_error_handling()
自定义异常类
class CustomError(Exception):
"""自定义异常基类"""
def __init__(self, message, code=None):
self.message = message
self.code = code
super().__init__(self.message)
def __str__(self):
if self.code:
return f"[{self.code}] {self.message}"
return self.message
class ValidationError(CustomError):
"""数据验证错误"""
pass
class BusinessError(CustomError):
"""业务逻辑错误"""
pass
# 使用自定义异常
def validate_age(age):
"""验证年龄"""
if not isinstance(age, int):
raise ValidationError("年龄必须是整数", code=1001)
if age < 0 or age > 150:
raise ValidationError(f"年龄 {age} 超出有效范围", code=1002)
return True
def process_user_data(age):
"""处理用户数据"""
try:
validate_age(age)
print(f"年龄 {age} 验证通过")
except ValidationError as e:
print(f"验证失败:{e}")
# 根据错误码处理
if e.code == 1001:
print("建议:请输入整数")
elif e.code == 1002:
print("建议:请输入0-150之间的年龄")
except Exception as e:
print(f"处理错误:{e}")
# 测试
process_user_data("25") # 类型错误
process_user_data(200) # 范围错误
process_user_data(25) # 正确
实际项目中的最佳实践
案例:完整的API调用封装
import time
import logging
from functools import wraps
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def retry_on_failure(max_retries=3, delay=1):
"""重试装饰器"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
last_exception = None
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except (ConnectionError, TimeoutError) as e:
last_exception = e
logger.warning(f"尝试 {attempt + 1}/{max_retries} 失败:{e}")
if attempt < max_retries - 1:
time.sleep(delay * (attempt + 1)) # 指数退避
logger.error(f"所有重试都失败")
raise last_exception
return wrapper
return decorator
class SafeAPIClient:
"""安全的API客户端"""
def __init__(self, base_url, api_key=None):
self.base_url = base_url
self.api_key = api_key
self.session = requests.Session()
if api_key:
self.session.headers.update({"Authorization": f"Bearer {api_key}"})
@retry_on_failure(max_retries=3)
def get_user_data(self, user_id):
"""获取用户数据(带重试机制)"""
try:
url = f"{self.base_url}/users/{user_id}"
response = self.session.get(url, timeout=10)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if response.status_code == 404:
logger.error(f"用户 {user_id} 不存在")
return None
elif response.status_code == 401:
logger.error("认证失败")
raise PermissionError("API密钥无效")
else:
raise
except requests.exceptions.ConnectionError:
logger.error("网络连接失败")
raise ConnectionError("无法连接到API服务器")
except requests.exceptions.Timeout:
logger.error("请求超时")
raise TimeoutError("API请求超时")
except Exception as e:
logger.exception(f"获取用户数据时发生未知错误")
raise
def close(self):
"""安全关闭会话"""
try:
self.session.close()
except Exception as e:
logger.error(f"关闭会话时出错:{e}")
# 使用示例
client = SafeAPIClient("https://api.example.com", api_key="your-api-key")
try:
user_data = client.get_user_data(12345)
if user_data:
print(f"用户数据:{user_data}")
except (ConnectionError, TimeoutError) as e:
print(f"网络错误:{e}")
except PermissionError as e:
print(f"权限错误:{e}")
finally:
client.close()
异常捕获的注意事项
常见陷阱和最佳实践
# ❌ 不好的做法:空except
try:
risky_operation()
except:
pass # 错误被忽略
# ✅ 好的做法:指定异常类型
try:
risky_operation()
except (ValueError, TypeError) as e:
logger.error(f"输入验证错误:{e}")
# ❌ 不好的做法:同时捕获异常又不处理
try:
result = calculate()
except Exception:
# 没有任何处理
pass
# ✅ 好的做法:始终进行适当的错误处理
try:
result = calculate()
except Exception as e:
logger.error(f"计算失败:{e}")
result = 0 # 设置默认值
raise # 或者重新抛出异常
# ❌ 不好的做法:过于宽泛的异常处理
try:
process_data()
except Exception:
print("出错了") # 丢失错误信息
# ✅ 好的做法:记录详细信息
try:
process_data()
except Exception as e:
logger.exception("处理数据时出错") # 记录完整堆栈跟踪
raise CustomError("数据处理失败", original_error=e)
- 精确捕获:尽量捕获特定异常类型
- 完整结构:充分利用 try-except-else-finally
- 适当记录:使用 logging 记录异常信息
- 重试机制:对临时性故障使用重试策略
- 资源清理:finally 或 with 语句确保资源释放
- 自定义异常:创建业务相关的异常类型
- 错误处理:不要忽略异常,要么处理要么重新抛出
这些实践能帮助你编写更健壮、更可维护的 Python 代码。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播