异常处理
基本语法
try :
result = 10 / 0
except ZeroDivisionError :
print ( "除零错误" )
except ( TypeError , ValueError ) as e:
print ( f "类型或值错误: { e } " )
except Exception as e:
print ( f "其他异常: { e } " )
else :
print ( f "结果: { result } " ) # 无异常时执行
finally :
print ( "完成" ) # 无论如何都执行
异常层次结构
BaseException
├── SystemExit # sys.exit()
├── KeyboardInterrupt # Ctrl+C
└── Exception
├── ArithmeticError
│ └── ZeroDivisionError
├── LookupError
│ ├── IndexError
│ └── KeyError
├── TypeError
├── ValueError
├── AttributeError
├── NameError
├── OSError
│ └── FileNotFoundError
├── RuntimeError
│ └── RecursionError
├── StopIteration
└── ImportError
└── ModuleNotFoundError
raise
def divide (a, b):
if b == 0 :
raise ValueError ( "除数不能为零" )
return a / b
# 重新抛出当前异常
try :
divide( 1 , 0 )
except ValueError :
print ( "已记录日志" )
raise # 原样重新抛出
# 异常链(保留原始上下文)
try :
int ( "abc" )
except ValueError as e:
raise RuntimeError ( "转换失败" ) from e
自定义异常
class AppError ( Exception ):
"""应用基础异常"""
class DatabaseError ( AppError ):
def __init__ (self, message: str , query: str = "" ):
super (). __init__ (message)
self .query = query
def __str__ (self):
return f " {super (). __str__ () } | query: {self .query } "
class NotFoundError ( DatabaseError ):
pass
try :
raise NotFoundError( "记录不存在" , "SELECT * FROM users WHERE id=99" )
except DatabaseError as e:
print (e) # 捕获所有 DatabaseError 子类
上下文管理器与异常
# with 确保资源释放
with open ( "file.txt" ) as f:
data = f.read() # 异常时也会自动关闭
# 自定义上下文管理器
from contextlib import contextmanager
@contextmanager
def managed_resource ():
print ( "获取资源" )
try :
yield "resource"
except Exception as e:
print ( f "处理异常: { e } " )
raise
finally :
print ( "释放资源" )
with managed_resource() as res:
print (res)
常用模式
# 安全访问字典
val = d.get( "key" ) # 不存在返回 None
# 安全类型转换
try :
n = int (user_input)
except ValueError :
n = 0
# 忽略特定异常
from contextlib import suppress
with suppress( FileNotFoundError ):
os.remove( "temp.txt" )
# 记录完整堆栈
import logging
try :
risky_operation()
except Exception :
logging.exception( "操作失败" ) # 自动包含 traceback
最佳实践
# ❌ 捕获过宽,吞掉所有异常
try :
do_something()
except Exception :
pass
# ✅ 只捕获预期的异常
try :
do_something()
except ( ValueError , TypeError ) as e:
handle_error(e)
# ❌ 用异常做流程控制(性能差)
try :
val = my_dict[ "key" ]
except KeyError :
val = "default"
# ✅ 用内置方法
val = my_dict.get( "key" , "default" )
相关链接