内置异常合集
Python 提供了许多内置的异常类,用于处理不同类型的错误情况。这些异常类大多数都继承自 BaseException
,而 Exception
是所有内建的非系统退出类异常的超类。以下是一些常见的 Python 内置异常及其简要说明:
继承自 Exception
的异常
ArithmeticError
:所有数值计算错误的基类。FloatingPointError
:浮点运算错误。OverflowError
:数值运算结果过大无法表示。ZeroDivisionError
:除(或取模)零(所有数据类型)。AssertionError
:断言语句失败。AttributeError
:尝试访问未知的对象属性或方法。EOFError
:没有内建输入,并且输入流已经关闭。ImportError
:导入模块/对象失败。ModuleNotFoundError
(Python 3.6+):导入模块时未找到指定的模块。LookupError
:无效数据查询的基类。IndexError
:使用的索引不存在(如列表索引超出范围)。KeyError
:字典中不存在请求的键。TypeError
:对类型的不适当操作(如尝试对非数字执行算术运算)。ValueError
:传入一个不合适的参数(即使类型正确),如函数期望正数却收到负数。EnvironmentError
(Python 3.3+ 已弃用,使用OSError
):操作系统错误的基类。IOError
(Python 3.x 中已重命名为OSError
,但IOError
仍然可用作为别名):输入/输出操作失败。OSError
:操作系统错误,如文件不存在或执行系统调用失败。FileNotFoundError
(Python 3.3+):尝试打开不存在的文件时引发。FileExistsError
(Python 3.3+):尝试创建已存在的文件或目录时引发。PermissionError
(Python 3.3+):尝试运行没有权限的操作时引发。IsADirectoryError
(Python 3.3+):在需要文件的地方提供了目录时引发。NotADirectoryError
(Python 3.3+):在需要目录的地方提供了文件时引发。
NameError
:尝试访问一个未声明的局部变量。UnboundLocalError
:尝试访问一个还未被赋值的局部变量。GlobalNameError
(不常用,实际上可能是指NameError
的一个情况):尝试访问一个未声明的全局变量(注意:Python 标准库中并没有直接名为GlobalNameError
的异常)。SyntaxError
:Python 解释器语法错误。IndentationError
:缩进错误(是SyntaxError
的子类)。TabError
:缩进不一致(是IndentationError
的子类)。SystemExit
:由sys.exit()
函数引发,表示 Python 解释器请求退出。KeyboardInterrupt
:用户中断执行(通常是 Ctrl+C)。MemoryError
:内存不足,无法为对象分配内存。RecursionError
(Python 3.5+):解释器检测到超出最大递归深度的递归调用。RuntimeError
:在程序执行期间遇到的错误,不在其他类别中。NotImplementedError
:尚未实现的方法。StopIteration
:迭代器没有更多的值。GeneratorExit
:生成器(generator)的close()
方法被调用。Warning
:基类的警告类别。UserWarning
:用户代码生成的警告。DeprecationWarning
:关于已被弃用功能的警告。PendingDeprecationWarning
:关于将来版本中将被弃用功能的警告。SyntaxWarning
:可疑的语法的警告。RuntimeWarning
:可疑的运行时行为的警告。FutureWarning
:关于构造将来语义将发生变化的警告。ImportWarning
:关于模块导入时可能出现问题的警告。UnicodeWarning
:关于 Unicode 相关问题的警告。BytesWarning
(Python 3.3+,提示与字节(bytes)和bytearray相关的潜在问题。
-
UnicodeError
:与Unicode相关的错误的基类。UnicodeDecodeError
:Unicode解码时的错误。UnicodeEncodeError
:Unicode编码时的错误。UnicodeTranslateError
:Unicode转换时的错误。
-
StopAsyncIteration
(Python 3.5+):必须通过异步迭代器对象的__anext__()
方法引发以停止迭代。 -
ConnectionError
:与连接相关的异常的基类。BrokenPipeError
:在已关闭写入的套接字上写入。ConnectionAbortedError
:连接尝试被对等方中止。ConnectionRefusedError
:连接尝试被对等方拒绝。ConnectionResetError
:连接由对等方重置。
-
TimeoutError
:系统函数在系统级别超时。 -
ReferenceError
:弱引用试图访问已经垃圾回收了的对象。 -
SystemError
:一般的解释器系统错误。 -
BlockingIOError
(Python 3.3+):操作将阻塞对象设置为非阻塞操作时引发。 -
ChildProcessError
(Python 3.3+):子进程上的操作失败。 -
ProcessLookupError
(Python 3.3+):进程不存在。
捕获并处理异常
ython 中的异常是一种用于处理在程序执行期间可能发生的错误的机制。当 Python 解释器遇到它认为不能处理的状况时,它会抛出一个异常。如果这个异常没有被捕获(处理),那么程序就会因为错误而终止。但是,通过使用 try...except 语句块,你可以捕获并处理这些异常,从而防止程序因为错误而完全停止。
异常的基础
- try 块:你尝试执行的代码块,如果其中发生异常,则执行将停止,并跳转到 except 块(如果有的话)。
- except 块:紧跟在 try 块后面的代码块,用于捕获并处理 try 块中发生的异常。
- else 块(可选):当 try 块中没有异常发生时执行的代码块。
- finally 块(可选):无论是否发生异常,都将执行的代码块。这对于执行清理操作(如关闭文件)很有用。
示例
try:
# 尝试执行的代码
result = 10 / 0
except ZeroDivisionError:
# 捕获除以零的异常
print("除数不能为0")
else:
# 如果没有异常发生,则执行
print("结果是:", result)
finally:
# 无论是否发生异常都会执行
print("执行结束")
#运行结果
除数不能为0
执行结束
捕获多个异常
你可以在同一个 except 子句中捕获多个异常,只需将异常类作为元组列出即可。
try:
# 尝试执行的代码
pass
except (ZeroDivisionError, ValueError) as e:
# 捕获除以零或值错误的异常
print(f"捕获到异常:{e}")
异常链
在 Python 3 中,raise
语句用于触发一个异常。这在你想要在某个特定条件下立即停止代码的执行,并报告一个错误时非常有用。一个异常处理块可以引发另一个异常,同时保留原始异常的上下文。这通过 raise ... from ...
语法实现。这样做的好处是,当新的异常被抛出时,调用者可以了解到新异常是由哪个原始异常触发的,这对于调试和日志记录特别有用。
语法结构如下:
try:
# 尝试执行的代码块
...
except SomeException as e:
# 异常处理器
# 可以在这里处理异常,比如记录日志、清理资源等
# 然后基于某种原因,决定抛出一个新的异常
raise NewException("这是新的异常信息") from e
但是,为了保留原始异常的上下文,你应该使用 raise ... from ...
语法:
try:
# 尝试执行的代码块
...
except SomeException as e:
# 异常处理器
# ...
# 抛出一个新的异常,并保留原始异常的上下文
raise NewException("这是新的异常信息,由原始异常触发") from e
在这个例子中,NewException
是被抛出的新异常,而 from e
表明这个新异常是由 e
(即 SomeException
的实例)触发的。当这个新的异常被捕获时,你可以使用 __cause__
属性来访问原始异常(e
),或者使用 traceback
模块来查看异常的完整调用栈。
这里是一个简单的例子来展示异常链的使用:
class MyError(Exception):
pass
try:
1 / 0 # 这将引发 ZeroDivisionError
except ZeroDivisionError as e:
# 捕获到 ZeroDivisionError,并抛出一个新的 MyError 异常
raise MyError("不能除以零") from e
# 如果你在更上层的异常处理器中捕获 MyError,你可以这样做:
try:
# 尝试执行可能抛出 MyError 的代码
...
except MyError as e:
print(f"捕获到 MyError: {e}")
# 如果需要,可以访问原始异常
if e.__cause__ is not None:
print(f"原始异常是: {e.__cause__}")
运行结果将是:
Traceback (most recent call last):
File "<your_script_name>.py", line X, in <module>
1 / 0 # 这将引发 ZeroDivisionError
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<your_script_name>.py", line Y, in <module>
raise MyError("不能除以零") from e
MyError: 不能除以零
注意:
- 这里的
X
和Y
是行号,它们将根据你的实际代码中的行号而变化。 - 首先,你会看到
ZeroDivisionError
的异常信息,因为1 / 0
引发了它,并且这个异常被except ZeroDivisionError as e:
捕获了。 - 然后,你会看到
MyError
的异常信息,这是因为它在except
块中被抛出了,并且由于没有被更外层的try-except
捕获,所以它被打印出来并导致程序终止。 - 重要的是,由于使用了
raise ... from ...
语法,Python 能够在MyError
的异常信息之后显示ZeroDivisionError
作为原始异常(或称为“直接原因”),尽管ZeroDivisionError
已经被捕获并处理了。
assert调试
语句
Python的assert
语句用于调试目的,它会在代码执行时测试一个条件,如果条件为False
,则引发一个AssertionError
异常。assert
语句主要用于捕获程序中的逻辑错误,而不是用于处理正常的程序流程控制(如使用if
语句)。
assert
语句的基本语法如下:
assert expression[, message]
expression
:要测试的条件表达式。message
(可选):如果条件为False
时,将显示的错误消息。如果未提供,将显示一个默认的错误消息。
如果expression
的结果为True
,则程序继续执行。如果expression
的结果为False
,则程序将引发一个AssertionError
异常,并可选地显示message
参数中指定的错误消息。
示例
# 正确的使用
assert 2 + 2 == 4, "2 + 2 不等于 4 !"
# 这行代码不会引发异常,因为条件为真
# 错误的使用(将引发AssertionError)
assert 1 + 1 == 3, "1 + 1 不等于 3 !"
# 这将引发AssertionError,并显示错误消息
# 没有错误消息的assert
assert 1 + 1 == 3
# 这也会引发AssertionError,但只显示默认的错误消息
注意事项
assert
语句主要用于调试目的,不应用于生产环境的程序逻辑控制。- 在某些情况下(如使用
-O
或--optimize
选项运行Python程序时),assert
语句可能会被忽略,以提高程序的运行速度。因此,不应依赖assert
语句来执行必要的程序逻辑。 - 对于需要确保在程序运行时始终满足的条件,应该使用其他形式的错误处理(如
if
语句和异常处理)。