2025-10-08 Python 标准库 10——内置异常
·
文章目录
1. Python内置异常概述
在Python中,所有异常均继承自BaseException类,是处理程序运行时错误的核心机制。合理理解和使用内置异常,能帮助开发者精准捕获错误、定位问题,并编写更健壮的代码。本章将系统梳理Python内置异常的分类、用法及核心特性。
1.1 异常的基本规则
- 继承关系:所有内置异常的根类是
BaseException,用户自定义异常推荐继承自Exception(而非BaseException,避免捕获系统级异常如SystemExit)。 - 异常捕获:
except子句会捕获目标异常及其所有子类(例如except Exception会捕获ValueError、TypeError等,但不会捕获BaseException的直接子类如KeyboardInterrupt)。 - 关联值:多数异常有“关联值”(如错误信息字符串),通过异常实例的
args属性可访问(例如except ValueError as e: print(e.args))。 - 版本差异:部分异常是后续版本新增的(如
ModuleNotFoundError在3.6+、ExceptionGroup在Python 3.11+),使用时需注意兼容性。
1.2 异常上下文(__context__、__cause__、__suppress_context__)
当异常嵌套引发时(如except块中再引发新异常),Python通过三个属性记录上下文关系,帮助调试时追溯完整错误链:
__context__:隐式上下文,自动记录“被处理过的前一个异常”(无需显式声明)。__cause__:显式原因,通过raise new_exc from original_exc声明,表明新异常是由原异常直接导致的。__suppress_context__:布尔值,显式声明from时自动设为True,表示屏蔽__context__的隐式展示。
# 1. 隐式上下文(__context__)
try:
# 第一步:触发KeyError
d = {"a": 1}
print(d["b"])
except KeyError as e1:
# 第二步:在except中触发AttributeError,无显式from
obj = type("Empty", (), {})() # 空对象
print(obj.no_such_attr) # 触发AttributeError
# 运行结果中,AttributeError的回溯会显示“During handling of the above exception, another exception occurred”
# 即通过__context__关联了KeyError
# 2. 显式原因(__cause__)
try:
# 第一步:触发ZeroDivisionError
1 / 0
except ZeroDivisionError as e1:
# 第二步:显式声明新异常的原因
raise ValueError("计算失败,因分母为零") from e1
# 运行结果中,ValueError的回溯会显示“The above exception was the direct cause of the following exception”
# 即通过__cause__关联了ZeroDivisionError,且__suppress_context__=True
1.3 异常的常用方法
1.3.1 add_note(note)(Python 3.11+)
为异常添加注释,注释会在回溯信息中显示,帮助补充错误上下文(如“请检查配置文件路径”)。
1.3.2 with_traceback(tb)
为异常绑定新的回溯对象(traceback),常用于异常转换时保留原始错误栈(如将自定义异常转换为标准异常)。
import sys
import traceback
def func():
# 触发基础异常
raise ValueError("原始错误:参数无效")
try:
func()
except ValueError as e:
# 1. 添加注释
e.add_note("补充说明:参数需为正整数")
e.add_note("建议检查调用func()时的传入值")
# 2. 获取原始回溯,转换为新异常并绑定回溯
tb = traceback.format_exc() # 获取回溯信息
new_exc = RuntimeError("函数执行失败")
new_exc = new_exc.with_traceback(sys.exc_info()[2]) # 绑定原始回溯
raise new_exc # 引发新异常
# 运行结果中,RuntimeError的回溯会包含:
# - 原始ValueError的错误栈(通过with_traceback绑定)
# - 两个补充注释(通过add_note添加)
2. 异常基类
基类主要用于派生其他异常,自身很少直接引发,核心作用是“分类异常”,便于批量捕获(如except ArithmeticError捕获所有算术类错误)。
2.1 BaseException:所有异常的根类
- 作用:Python中所有异常的顶层父类,包含系统级异常(如
SystemExit、KeyboardInterrupt)和应用级异常(Exception的子类)。 - 注意:不建议用户自定义异常直接继承
BaseException,否则可能捕获到系统级异常(如sys.exit()触发的SystemExit),导致程序无法正常退出。 - 核心属性/方法:
args:异常的关联值元组(如ValueError("a", "b").args == ("a", "b"))。__traceback__:异常的回溯对象。add_note(note)、with_traceback(tb)(见1.3节)。
# SystemExit继承自BaseException,except Exception无法捕获
try:
import sys
sys.exit(1) # 触发SystemExit
except Exception as e:
print("捕获到Exception:", e) # 不会执行
except BaseException as e:
print(f"捕获到BaseException: {type(e).__name__}") # 执行,输出“捕获到BaseException: SystemExit”
2.2 Exception:应用级异常的基类
- 作用:所有“非系统级异常”的父类(如
ValueError、TypeError),是用户自定义异常的推荐基类。 - 特点:
except Exception可捕获绝大多数应用逻辑错误,但不会捕获BaseException的直接子类(如KeyboardInterrupt、SystemExit),避免干扰系统级操作。
# 自定义异常:继承自Exception
class ConfigError(Exception):
"""配置文件相关错误的基类"""
pass
class ConfigNotFoundError(ConfigError):
"""配置文件不存在的错误"""
def __init__(self, path):
self.path = path
super().__init__(f"配置文件不存在:{path}")
# 使用自定义异常
try:
config_path = "config.ini"
with open(config_path, "r") as f:
pass
except FileNotFoundError:
raise ConfigNotFoundError(config_path) from None # 屏蔽原异常的上下文
# 捕获自定义异常
try:
raise ConfigNotFoundError("config.ini")
except ConfigError as e:
print(f"配置错误:{e}") # 输出“配置错误:配置文件不存在:config.ini”
2.3 其他核心基类
| 基类 | 作用 | 子类示例 |
|---|---|---|
ArithmeticError |
算术运算相关错误的基类 | ZeroDivisionError、OverflowError |
LookupError |
序列/映射查找错误的基类(如索引、键不存在) | IndexError、KeyError |
OSError |
系统调用相关错误的基类(如文件操作、网络连接) | FileNotFoundError、PermissionError |
Warning |
警告类别的基类(非错误,仅提示潜在风险) | DeprecationWarning、FutureWarning |
# 批量捕获算术类错误(ArithmeticError的子类)
try:
result1 = 1 / 0 # ZeroDivisionError
# result2 = 2 ** 1000000 # 极端情况下触发OverflowError(整数一般不会,浮点数可能)
except ArithmeticError as e:
print(f"算术错误:{type(e).__name__}: {e}") # 输出“算术错误:ZeroDivisionError: division by zero”
# 批量捕获查找类错误(LookupError的子类)
data = [1, 2, 3]
d = {"a": 1}
try:
# print(data[10]) # IndexError
print(d["b"]) # KeyError
except LookupError as e:
print(f"查找错误:{type(e).__name__}: {e}") # 输出“查找错误:KeyError: 'b'”
3. 常用具体异常
具体异常是程序运行中最常触发的异常,需掌握其触发场景和捕获方式。
3.1 断言与属性相关异常
3.1.1 AssertionError
- 触发场景:
assert语句的条件为False时触发(用于调试阶段验证假设,如“参数必须为正”)。 - 注意:Python运行时加
-O(优化模式)会禁用assert,AssertionError不会触发。
# 断言条件:参数必须大于0
def func(x):
assert x > 0, f"参数x必须为正,当前为{x}" # 条件不满足时触发AssertionError
return x * 2
try:
func(-1)
except AssertionError as e:
print(f"AssertionError: {e}") # 输出“AssertionError: 参数x必须为正,当前为-1”
3.1.2 AttributeError
- 触发场景:访问对象不存在的属性(或赋值给不允许赋值的属性,如
int的__name__)。
# 1. 访问不存在的属性
obj = type("MyClass", (), {"attr1": 1})() # 自定义类实例,仅含attr1
try:
print(obj.attr2) # 访问不存在的attr2
except AttributeError as e:
print(f"AttributeError: {e}") # 输出“AttributeError: 'MyClass' object has no attribute 'attr2'”
# 2. 3.10+ 新增name和obj属性,可直接获取出错的属性名和对象
try:
obj.attr2
except AttributeError as e:
print(f"属性名:{e.name}, 对象:{e.obj}") # 输出“属性名:attr2, 对象:<__main__.MyClass object at 0x...>”
3.2 查找相关异常
3.2.1 IndexError
- 触发场景:序列(如列表、元组)的索引超出范围(切片会静默截断,不会触发)。
lst = [1, 2, 3]
try:
print(lst[5]) # 索引5超出范围(最大索引为2)
except IndexError as e:
print(f"IndexError: {e}") # 输出“IndexError: list index out of range”
# 切片不会触发IndexError(静默截断)
print(lst[5:]) # 输出“[]”,无异常
3.2.2 KeyError
- 触发场景:字典(或其他映射类型)中查找不存在的键。
d = {"name": "Alice", "age": 25}
try:
print(d["gender"]) # 查找不存在的键gender
except KeyError as e:
print(f"KeyError: {e}") # 输出“KeyError: 'gender'”
# 推荐用get()方法避免KeyError
print(d.get("gender", "未知")) # 输出“未知”,无异常
3.3 类型与值相关异常
3.3.1 TypeError
- 触发场景:操作或函数应用于“类型不匹配”的对象(如用整数加字符串、调用非可调用对象)。
# 1. 类型不匹配的运算
try:
result = 1 + "2" # 整数 + 字符串,类型不匹配
except TypeError as e:
print(f"TypeError: {e}") # 输出“TypeError: unsupported operand type(s) for +: 'int' and 'str'”
# 2. 调用非可调用对象
x = 123 # 整数不可调用
try:
x()
except TypeError as e:
print(f"TypeError: {e}") # 输出“TypeError: 'int' object is not callable”
3.3.2 ValueError
- 触发场景:参数类型正确,但值不合法(如将非数字字符串转为整数、列表中删除不存在的元素)。
# 1. 类型正确但值不合法的转换
try:
int("abc") # 字符串类型正确,但值不是数字
except ValueError as e:
print(f"ValueError: {e}") # 输出“ValueError: invalid literal for int() with base 10: 'abc'”
# 2. 列表中删除不存在的元素
lst = [1, 2, 3]
try:
lst.remove(4) # 元素4不存在于列表
except ValueError as e:
print(f"ValueError: {e}") # 输出“ValueError: list.remove(x): x not in list”
3.4 导入与名称相关异常
3.4.1 ImportError与ModuleNotFoundError(Python 3.6+)
ImportError:导入模块失败(如模块内缺少指定名称)。ModuleNotFoundError:ImportError的子类,特指“模块本身不存在”(3.6+新增,更精准)。
# 1. 模块不存在(触发ModuleNotFoundError)
try:
import non_existent_module # 模块不存在
except ModuleNotFoundError as e:
print(f"ModuleNotFoundError: {e}") # 输出“ModuleNotFoundError: No module named 'non_existent_module'”
# 2. 模块存在但缺少指定名称(触发ImportError)
try:
from math import non_existent_func # math模块无此函数
except ImportError as e:
print(f"ImportError: {e}") # 输出“ImportError: cannot import name 'non_existent_func' from 'math'”
3.4.2 NameError与UnboundLocalError
NameError:引用未定义的局部或全局名称。UnboundLocalError:NameError的子类,特指“函数内引用未绑定的局部变量”(如局部变量在赋值前被引用)。
# 1. 引用未定义的全局名称(NameError)
try:
print(undefined_var) # undefined_var未定义
except NameError as e:
print(f"NameError: {e}") # 输出“NameError: name 'undefined_var' is not defined”
# 2. 函数内引用未绑定的局部变量(UnboundLocalError)
def func():
print(x) # 局部变量x在赋值前被引用
x = 10
try:
func()
except UnboundLocalError as e:
print(f"UnboundLocalError: {e}") # 输出“UnboundLocalError: local variable 'x' referenced before assignment”
3.5 运行时相关异常
3.5.1 RuntimeError
- 触发场景:捕获到“无法归类到其他异常”的运行时错误(如递归深度超出限制的旧版本、解释器内部错误)。
3.5.2 RecursionError(Python 3.5+)
RuntimeError的子类,触发场景:递归调用深度超出Python默认限制(默认约1000层)。
def recursive_func(n):
if n == 0:
return
recursive_func(n - 1) # 递归调用
try:
recursive_func(2000) # 递归深度2000,超出默认限制
except RecursionError as e:
print(f"RecursionError: {e}") # 输出“RecursionError: maximum recursion depth exceeded in comparison”
# 可通过sys.setrecursionlimit()调整限制(不建议过大,可能导致栈溢出)
import sys
sys.setrecursionlimit(3000) # 调整为3000层
3.5.3 NotImplementedError
RuntimeError的子类,触发场景:抽象基类的方法要求子类重写,但子类未实现;或功能暂未开发完成。
class BaseService:
def process(self):
# 抽象方法,要求子类重写
raise NotImplementedError("子类必须实现process()方法")
class UserService(BaseService):
# 未重写process()方法
pass
try:
service = UserService()
service.process()
except NotImplementedError as e:
print(f"NotImplementedError: {e}") # 输出“NotImplementedError: 子类必须实现process()方法”
3.6 迭代相关异常
3.6.1 StopIteration
- 触发场景:迭代器(如生成器、
next()函数)无更多元素可返回时触发;生成器返回值时也会触发(返回值作为StopIteration的value属性)。
# 1. 迭代器耗尽
it = iter([1, 2, 3])
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
try:
print(next(it)) # 无更多元素,触发StopIteration
except StopIteration as e:
print(f"StopIteration: {e.value}") # 输出“StopIteration: None”(无返回值时value为None)
# 2. 生成器返回值触发StopIteration
def gen():
yield 1
yield 2
return "生成器结束" # 返回值作为StopIteration的value
g = gen()
print(next(g)) # 1
print(next(g)) # 2
try:
next(g)
except StopIteration as e:
print(f"StopIteration value: {e.value}") # 输出“StopIteration value: 生成器结束”
3.6.2 StopAsyncIteration(Python 3.5+)
- 触发场景:异步迭代器(
async for)无更多元素可返回时触发,用法与StopIteration类似(针对异步场景)。
3.7 系统与内存相关异常
3.7.1 KeyboardInterrupt
- 触发场景:用户按下中断键(如
Ctrl+C),用于终止运行中的程序。 - 注意:继承自
BaseException,except Exception无法捕获,需显式捕获KeyboardInterrupt。
import time
try:
print("程序运行中,按Ctrl+C终止...")
while True:
time.sleep(1) # 模拟耗时操作
except KeyboardInterrupt:
print("\n程序被用户中断(Ctrl+C)") # 捕获Ctrl+C,优雅退出
3.7.2 MemoryError
- 触发场景:操作耗尽内存且无法通过删除对象挽救时触发(如创建超大列表、处理超大文件)。
- 注意:Python整数支持任意长度,通常不会因整数过大触发,多发生于大量对象占用内存时。
try:
# 尝试创建超大列表(约占用4GB内存,视系统内存而定)
large_list = [0] * (10 ** 9)
except MemoryError as e:
print(f"MemoryError: {e}") # 输出“MemoryError:”(部分系统可能无具体信息)
3.7.3 SystemExit
- 触发场景:调用
sys.exit(n)时触发,用于终止程序(n为退出状态码,0表示正常退出)。 - 注意:继承自
BaseException,except Exception无法捕获,程序退出时默认不打印回溯。
4. OS相关异常(OSError子类)
OSError是系统调用错误的基类,Python 3.3+将IOError、WindowsError等合并为OSError,并根据系统错误码派生出多个子类,使错误分类更精准。
4.1 文件相关异常
4.1.1 FileNotFoundError
- 触发场景:操作的文件或目录不存在(如
open()不存在的文件、os.remove()不存在的路径)。
try:
# 打开不存在的文件
with open("non_existent_file.txt", "r") as f:
content = f.read()
except FileNotFoundError as e:
print(f"FileNotFoundError: {e.filename} 不存在") # 输出“FileNotFoundError: non_existent_file.txt 不存在”
4.1.2 FileExistsError
- 触发场景:试图创建已存在的文件或目录(如
os.mkdir()创建已存在的目录)。
import os
try:
os.mkdir("test_dir") # 第一次创建成功
os.mkdir("test_dir") # 第二次创建,目录已存在
except FileExistsError as e:
print(f"FileExistsError: {e.filename} 已存在") # 输出“FileExistsError: test_dir 已存在”
4.1.3 IsADirectoryError与NotADirectoryError
IsADirectoryError:对目录执行文件操作(如os.remove()删除目录)。NotADirectoryError:对文件执行目录操作(如os.listdir()列出文件的内容)。
import os
# 1. IsADirectoryError:删除目录(需用os.rmdir())
try:
os.remove("test_dir") # test_dir是目录,os.remove()用于删除文件
except IsADirectoryError as e:
print(f"IsADirectoryError: {e.filename} 是目录") # 输出“IsADirectoryError: test_dir 是目录”
# 2. NotADirectoryError:列出文件的内容(os.listdir()用于目录)
try:
os.listdir("test_file.txt") # test_file.txt是文件
except NotADirectoryError as e:
print(f"NotADirectoryError: {e.filename} 不是目录") # 输出“NotADirectoryError: test_file.txt 不是目录”
4.2 连接相关异常(ConnectionError子类)
ConnectionError是网络连接错误的基类,子类包括:
ConnectionRefusedError:连接被对方拒绝(如目标端口未开放)。ConnectionAbortedError:连接被对方中止(如对方主动关闭连接)。ConnectionResetError:连接被对方重置(如网络中断后对方重启)。BrokenPipeError:写入已关闭的管道或套接字(如对方已断开,仍尝试写入)。
import socket
# 尝试连接未开放的端口(如本地9999端口无服务)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(("localhost", 9999))
except ConnectionRefusedError as e:
print(f"ConnectionRefusedError: {e}") # 输出“ConnectionRefusedError: [Errno 111] Connection refused”
finally:
s.close()
4.3 权限与进程相关异常
4.3.1 PermissionError
- 触发场景:操作无足够权限(如写入只读文件、删除系统保护的目录)。
try:
# 尝试写入只读文件(假设test_readonly.txt权限为只读)
with open("test_readonly.txt", "w") as f:
f.write("test")
except PermissionError as e:
print(f"PermissionError: 无权限操作 {e.filename}") # 输出“PermissionError: 无权限操作 test_readonly.txt”
4.3.2 ProcessLookupError
- 触发场景:操作的进程不存在(如
os.kill()杀死不存在的进程)。
import os
# 尝试杀死不存在的进程(假设PID 99999无对应进程)
try:
os.kill(99999, 9) # 9是SIGKILL信号
except ProcessLookupError as e:
print(f"ProcessLookupError: 进程 {e.pid} 不存在") # 输出“ProcessLookupError: 进程 99999 不存在”
4.3.3 TimeoutError(Python 3.3+)
- 触发场景:系统调用超时(如
socket连接超时、os.waitpid()超时)。
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2) # 设置超时时间2秒
try:
# 连接无法访问的IP(如192.168.1.254,无响应)
s.connect(("192.168.1.254", 80))
except TimeoutError as e:
print(f"TimeoutError: 连接超时") # 输出“TimeoutError: timed out”
finally:
s.close()
5. 警告类别(Warning子类)
警告(Warning)不是错误,用于提示“潜在风险”(如使用已弃用的API、模糊的语法),默认不中断程序运行。需通过warnings模块控制警告的显示(如忽略、转为异常)。
5.1 开发相关警告
5.1.1 DeprecationWarning
- 用途:提示“API已弃用,供开发者参考”(如旧版本的
urllib2模块)。 - 默认行为:默认被警告过滤器忽略,仅在
__main__模块或开发模式(python -X dev)下显示。
5.1.2 PendingDeprecationWarning
- 用途:提示“API即将弃用,但目前仍可用”(较少使用,通常直接用
DeprecationWarning)。
5.2 用户与运行时警告
5.2.1 UserWarning
- 用途:用户代码自定义的警告(如“输入参数不推荐,建议使用新参数”)。
5.2.2 FutureWarning
- 用途:提示“API未来行为会改变,供应用用户参考”(如
pandas的旧版函数参数)。
5.2.3 RuntimeWarning
- 用途:提示“运行时的模糊行为”(如整数除以零的浮点数结果
inf、无效的复数运算)。
import warnings
# 1. 发出警告
def func(old_param=None, new_param=None):
if old_param is not None:
# 发出UserWarning,提示旧参数已不推荐
warnings.warn(
"old_param已不推荐使用,请使用new_param",
UserWarning,
stacklevel=2 # 正确定位警告的调用栈
)
return new_param or old_param
# 2. 控制警告显示(设为“始终显示”)
warnings.simplefilter("always", UserWarning)
# 3. 调用函数触发警告
func(old_param=10)
# 运行结果:
# UserWarning: old_param已不推荐使用,请使用new_param
# warnings.warn(...)
# 4. 将警告转为异常(用于严格检查)
warnings.simplefilter("error", UserWarning)
try:
func(old_param=10)
except UserWarning as e:
print(f"捕获到警告转为的异常:{e}") # 输出“捕获到警告转为的异常:old_param已不推荐使用,请使用new_param”
5.3 编码与资源警告
EncodingWarning(Python 3.10+):提示“编码相关的潜在问题”(如文件编码自动检测不准确)。UnicodeWarning:提示“Unicode相关的潜在问题”(如字节串解码为Unicode时的模糊字符)。ResourceWarning:提示“资源未正确释放”(如文件未关闭、socket未关闭),默认仅在开发模式下显示。
6. 异常组(Python 3.11+)
Python 3.11+ 引入异常组(BaseExceptionGroup和ExceptionGroup),用于一次性引发多个不相关的异常(如并行任务中的多个错误),并通过except*语法精准捕获。
6.1 核心概念
BaseExceptionGroup:继承自BaseException,可包装任意异常(包括系统级异常如KeyboardInterrupt)。ExceptionGroup:继承自Exception,仅可包装Exception的子类(应用级异常),构造器若传入非Exception子类会触发TypeError。- 关键属性:
message:异常组的描述信息(如“并行任务中的多个错误”)。exceptions:包装的异常元组。
6.2 引发与捕获异常组
# 1. 引发ExceptionGroup(仅包装应用级异常)
try:
raise ExceptionGroup(
"批量处理数据时的错误", # message
[
ValueError("数据1格式无效"),
KeyError("数据2缺少关键字段"),
TypeError("数据3类型不匹配")
]
)
except* ValueError as eg:
# 捕获异常组中所有ValueError
print(f"捕获到ValueError异常组:{eg.message}")
for e in eg.exceptions:
print(f"- {e}") # 输出“- 数据1格式无效”
except* (KeyError, TypeError) as eg:
# 捕获异常组中所有KeyError和TypeError
print(f"\n捕获到KeyError/TypeError异常组:{eg.message}")
for e in eg.exceptions:
print(f"- {type(e).__name__}: {e}") # 输出“- KeyError: 数据2缺少关键字段”和“- TypeError: 数据3类型不匹配”
# 2. 引发BaseExceptionGroup(可包装系统级异常)
try:
raise BaseExceptionGroup(
"包含系统级异常的组",
[
ValueError("应用错误"),
KeyboardInterrupt("用户中断") # 系统级异常
]
)
except* Exception as eg:
# 仅捕获应用级异常(ValueError),KeyboardInterrupt不会被捕获
print(f"\n捕获到应用级异常组:{eg.exceptions}") # 输出“捕获到应用级异常组:(ValueError('应用错误'),)”
为方便查阅,以下是Python内置异常的核心继承关系(精简版):
BaseException
├── BaseExceptionGroup # 异常组(Python 3.11+)
├── GeneratorExit # 生成器关闭时触发
├── KeyboardInterrupt # 用户中断(Ctrl+C)
├── SystemExit # 程序退出(sys.exit())
└── Exception # 应用级异常基类
├── ArithmeticError # 算术错误基类
│ ├── FloatingPointError # 浮点运算错误(极少用)
│ ├── OverflowError # 数值溢出(极少用)
│ └── ZeroDivisionError # 除以零
├── AssertionError # assert语句失败
├── AttributeError # 访问不存在的属性
├── BufferError # 缓冲区操作错误
├── EOFError # 输入到达EOF无数据
├── ExceptionGroup # 应用级异常组(Python 3.11+)
├── ImportError # 导入错误
│ └── ModuleNotFoundError # 模块不存在(Python 3.6+)
├── LookupError # 查找错误基类
│ ├── IndexError # 序列索引超出范围
│ └── KeyError # 映射键不存在
├── MemoryError # 内存耗尽
├── NameError # 名称未定义
│ └── UnboundLocalError # 局部变量未绑定
├── OSError # 系统错误基类
│ ├── BlockingIOError # 非阻塞操作阻塞
│ ├── ChildProcessError # 子进程操作失败
│ ├── ConnectionError # 连接错误基类
│ │ ├── BrokenPipeError # 管道已关闭仍写入
│ │ ├── ConnectionAbortedError # 连接被中止
│ │ ├── ConnectionRefusedError # 连接被拒绝
│ │ └── ConnectionResetError # 连接被重置
│ ├── FileExistsError # 创建已存在的文件/目录
│ ├── FileNotFoundError # 文件/目录不存在
│ ├── InterruptedError # 系统调用被信号中断
│ ├── IsADirectoryError # 对目录执行文件操作
│ ├── NotADirectoryError # 对文件执行目录操作
│ ├── PermissionError # 权限不足
│ ├── ProcessLookupError # 进程不存在
│ └── TimeoutError # 系统调用超时(Python 3.3+)
├── ReferenceError # 弱引用访问已回收对象
├── RuntimeError # 未归类的运行时错误
│ ├── NotImplementedError # 方法未实现
│ ├── PythonFinalizationError # 解释器终结时操作被阻止(Python 3.13+)
│ └── RecursionError # 递归深度超出限制(Python 3.5+)
├── StopAsyncIteration # 异步迭代器结束(Python 3.5+)
├── StopIteration # 迭代器结束
├── SyntaxError # 语法错误
│ └── IndentationError # 缩进错误
│ └── TabError # 制表符与空格混用
├── SystemError # 解释器内部错误
├── TypeError # 类型不匹配
├── ValueError # 值不合法
│ └── UnicodeError # Unicode编码/解码错误
│ ├── UnicodeDecodeError # 解码错误
│ ├── UnicodeEncodeError # 编码错误
│ └── UnicodeTranslateError # 转写错误
└── Warning # 警告基类
├── BytesWarning # bytes/bytearray相关警告
├── DeprecationWarning # API已弃用(开发者参考)
├── EncodingWarning # 编码相关警告(Python 3.10+)
├── FutureWarning # API未来行为改变(用户参考)
├── ImportWarning # 导入相关警告
├── PendingDeprecationWarning # API即将弃用
├── ResourceWarning # 资源未正确释放
├── RuntimeWarning # 运行时模糊行为
├── SyntaxWarning # 语法模糊
├── UnicodeWarning # Unicode相关警告
└── UserWarning # 用户自定义警告
7. 总结
- 精准捕获:避免用
except Exception捕获所有异常,应针对性捕获具体异常(如except ValueError),防止掩盖系统级异常(如KeyboardInterrupt)。 - 异常上下文:使用
raise new_exc from original_exc显式关联异常原因,帮助调试时追溯完整错误链。 - 自定义异常:继承
Exception而非BaseException,并通过子类细化错误类型(如ConfigError→ConfigNotFoundError)。 - 版本兼容:注意新增异常的版本(如
ExceptionGroup在Python 3.11+),避免在低版本环境中使用。
更多推荐



所有评论(0)