本文目录导读:

我来用实际案例详细说明Python异常的分类和处理方法。
异常分类概览
# 异常体系结构
BaseException
├── SystemExit # 解释器退出
├── KeyboardInterrupt # 用户中断(Ctrl+C)
├── GeneratorExit # 生成器退出
└── Exception # 大多数异常基类
├── AttributeError # 属性错误
├── IOError # I/O错误
├── ImportError # 导入错误
├── IndexError # 索引错误
├── KeyError # 键错误
├── NameError # 名称错误
├── TypeError # 类型错误
├── ValueError # 值错误
├── ZeroDivisionError # 除零错误
└── ...
常见异常区分案例
# 案例1:不同类型异常对比
def exception_comparison():
# 1. IndexError vs KeyError
my_list = [1, 2, 3]
my_dict = {'a': 1, 'b': 2}
try:
print(my_list[5]) # IndexError: list index out of range
except IndexError:
print("索引越界错误!")
try:
print(my_dict['c']) # KeyError: 'c'
except KeyError:
print("键不存在错误!")
# 2. ValueError vs TypeError
try:
int("abc") # ValueError: invalid literal
except ValueError:
print("值转换错误!")
try:
"123" + 456 # TypeError: can only concatenate str (not "int") to str
except TypeError:
print("类型不匹配错误!")
# 3. AttributeError vs NameError
try:
my_list.appendd(4) # AttributeError: 'list' object has no attribute 'appendd'
except AttributeError:
print("属性不存在错误!")
try:
print(undefined_var) # NameError: name 'undefined_var' is not defined
except NameError:
print("变量未定义错误!")
exception_comparison()
实际业务场景异常处理
class DataProcessor:
"""数据处理类,展示各种异常处理"""
def process_user_data(self, user_data):
"""
处理用户数据的完整异常处理示例
"""
try:
# 1. 检查数据类型
if not isinstance(user_data, dict):
raise TypeError(f"期望dict类型,收到{type(user_data)}")
# 2. 检查必要字段
required_fields = ['name', 'age', 'email']
for field in required_fields:
if field not in user_data:
raise KeyError(f"缺少必要字段: {field}")
# 3. 数据验证
name = user_data['name']
if not isinstance(name, str) or len(name) == 0:
raise ValueError("姓名必须是非空字符串")
age = user_data['age']
if not isinstance(age, int) or age < 0 or age > 150:
raise ValueError(f"年龄不合法: {age}")
# 4. 处理业务逻辑
result = self._calculate_score(age)
# 5. 文件操作可能出错
with open(f"user_{name}.txt", 'w') as f:
f.write(str(result))
return result
except TypeError as e:
print(f"类型错误: {e}")
return None
except KeyError as e:
print(f"键错误: {e}")
return None
except ValueError as e:
print(f"值错误: {e}")
return None
except IOError as e:
print(f"文件I/O错误: {e}")
return None
except Exception as e:
print(f"未知错误: {type(e).__name__}: {e}")
return None
def _calculate_score(self, age):
"""计算分数(可能抛出除零错误)"""
try:
return 100 / (age - 30) # 当age=30时触发ZeroDivisionError
except ZeroDivisionError:
print("警告:年龄恰好为30,使用默认值")
return 0
# 使用示例
processor = DataProcessor()
# 测试各种异常情况
test_cases = [
"not a dict", # TypeError
{"name": "Alice"}, # KeyError (缺少age和email)
{"name": "", "age": 25, "email": "a@b.com"}, # ValueError (空姓名)
{"name": "Bob", "age": 200, "email": "b@c.com"}, # ValueError (年龄过大)
{"name": "Charlie", "age": 30, "email": "c@d.com"}, # ZeroDivisionError
{"name": "David", "age": 25, "email": "d@e.com"}, # 正常情况
]
for i, test_data in enumerate(test_cases, 1):
print(f"\n测试用例 {i}:")
result = processor.process_user_data(test_data)
print(f"处理结果: {result}")
自定义异常类(专业做法)
class CustomBusinessError(Exception):
"""自定义业务异常基类"""
pass
class ValidationError(CustomBusinessError):
"""数据验证错误"""
def __init__(self, field, message):
self.field = field
self.message = message
super().__init__(f"字段 '{field}' 验证失败: {message}")
class DatabaseError(CustomBusinessError):
"""数据库操作错误"""
def __init__(self, operation, table, message):
self.operation = operation
self.table = table
self.message = message
super().__init__(f"数据库操作 '{operation}' 在表 '{table}' 上失败: {message}")
class NetworkError(CustomBusinessError):
"""网络错误"""
def __init__(self, url, status_code, message):
self.url = url
self.status_code = status_code
self.message = message
super().__init__(f"访问 {url} 失败,状态码: {status_code}, 错误: {message}")
# 使用自定义异常
def business_operation():
try:
# 模拟各种业务错误
raise ValidationError("email", "邮箱格式不正确")
# 或
# raise DatabaseError("INSERT", "users", "重复的主键")
# 或
# raise NetworkError("https://api.example.com", 500, "服务器内部错误")
except ValidationError as e:
print(f"验证错误: {e}")
print(f"错误字段: {e.field}")
except DatabaseError as e:
print(f"数据库错误: {e}")
print(f"操作: {e.operation}, 表: {e.table}")
except NetworkError as e:
print(f"网络错误: {e}")
print(f"URL: {e.url}, 状态码: {e.status_code}")
except CustomBusinessError as e:
print(f"业务错误: {e}")
异常处理最佳实践
def best_practices():
"""
异常处理最佳实践示例
"""
# 1. 具体异常优先,通用异常在后
try:
risky_operation()
except ValueError:
# 具体异常处理
pass
except TypeError:
# 具体异常处理
pass
except Exception:
# 通用异常处理(兜底)
pass
# 2. 尽量捕获特定异常,避免裸except:
# 不建议:except: # 捕获所有异常,包括SystemExit
# 3. 使用else子句(无异常时执行)
try:
result = risky_operation()
except ValueError as e:
print(f"错误: {e}")
else:
print(f"成功: {result}") # 只有在try块成功时才执行
# 4. 使用finally子句(始终执行)
file = None
try:
file = open("data.txt", 'r')
data = file.read()
except FileNotFoundError:
print("文件不存在")
finally:
if file:
file.close() # 确保文件被关闭
# 5. 异常链(保留原始异常信息)
try:
try:
int("abc")
except ValueError as e:
raise RuntimeError("数字转换失败") from e # 保留原始异常
def risky_operation():
"""模拟有风险的操作"""
import random
if random.random() < 0.5:
raise ValueError("随机错误")
return "success"
快速诊断指南
def diagnose_exception(exc):
"""
异常诊断助手函数
"""
exception_map = {
IndexError: "列表/元组索引超出范围",
KeyError: "字典键不存在",
ValueError: "值不符合预期格式",
TypeError: "操作或函数应用于不适当类型的对象",
AttributeError: "对象没有这个属性/方法",
NameError: "变量未定义",
ZeroDivisionError: "除零错误",
FileNotFoundError: "文件不存在",
ImportError: "模块导入失败",
SyntaxError: "代码语法错误",
IndentationError: "缩进错误",
}
exc_type = type(exc)
if exc_type in exception_map:
return f"{exception_map[exc_type]}: {exc}"
else:
return f"未知异常类型 {exc_type.__name__}: {exc}"
# 使用示例
try:
1/0
except Exception as e:
print(diagnose_exception(e)) # 除零错误: division by zero
- 区分方法:根据错误信息和异常类型名称判断
- 处理原则:具体异常优先,通用异常兜底
- 最佳实践:
- 只捕获你能处理的异常
- 使用自定义异常封装业务逻辑
- 保持异常链完整
- 合理使用else和finally
好的异常处理不是避免异常,而是优雅地处理异常!
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播