Python 的异常处理机制允许程序在发生错误时采取适当的应对措施,而不会立即终止运行。通过异常处理,你可以捕获并处理运行时的错误,从而使程序更加健壮和稳定。
异常处理的基本结构
Python 使用 try-except
结构来处理异常。基本语法如下:
try:
# 尝试执行的代码
except ExceptionType:
# 如果发生指定类型的异常,执行这段代码
1. 基本的 try-except
结构
try:
x = 10 / 0 # 可能会引发异常的代码
except ZeroDivisionError:
print("除数不能为零")
在这个例子中,当程序尝试执行 10 / 0
时,会抛出 ZeroDivisionError
。except
块捕获到这个异常,并输出相应的信息,而不是让程序崩溃。
2. 捕获多个异常
你可以通过多个 except
块捕获不同类型的异常:
try:
x = int(input("请输入一个数字: "))
result = 10 / x
except ValueError:
print("输入的不是一个有效的数字")
except ZeroDivisionError:
print("不能除以零")
在这个例子中,可能发生两种异常:用户输入的不是一个有效的数字(ValueError
),或者用户输入了零(ZeroDivisionError
)。不同的异常会触发不同的 except
块。
如果想要对多种异常执行相同的处理操作:
try:
x = int(input("请输入一个数字: "))
result = 10 / x
except (ValueError, ZeroDivisionError):
print('输入的数字有误,请检查输入。')
3. 捕获所有异常
如果你不确定会发生什么异常,可以使用 Exception
类捕获所有异常:
try:
x = int(input("请输入一个数字: "))
result = 10 / x
except Exception as e:
print(f"发生了异常: {e}")
这种方式会捕获所有的异常,并将异常信息存储在变量 e
中,可以在 except
块中使用。
4. else
块
else
块在 try
块中代码没有引发异常时执行:
try:
x = int(input("请输入一个数字: "))
result = 10 / x
except ZeroDivisionError:
print("不能除以零")
except ValueError:
print("输入的不是一个有效的数字")
else:
print(f"结果是: {result}")
在这个例子中,如果没有发生异常,程序会执行 else
块中的代码,并输出计算结果。
5. finally
块
finally
块无论是否发生异常,都会执行,常用于释放资源或进行清理操作:
try:
file = open("example.txt", "r")
content = file.read()
except FileNotFoundError:
print("文件未找到")
finally:
file.close()
print("文件已关闭")
在这个例子中,无论是否发生 FileNotFoundError
,finally
块都会确保文件被关闭。
注意:即使在函数中有return 返回 finally中的类容也会被执行。
def test():
try:
x = int(input("输入数字:"))
result = 10 / x
print(f"结果为{result}。")
return
except (ZeroDivisionError, ValueError):
print("发现错误。")
return
finally:
print("最后执行finally。")
test()
# 输入数字:1
# 结果为10.0
# 最后执行finally。
# 输入数字:0
# 发现错误。
# 最后执行finally。
6. 自定义异常
你可以通过继承 Exception
类来自定义异常:
class CustomError(Exception):
def __init__(self, message):
self.message = message
try:
raise CustomError("这是一个自定义异常")
except CustomError as e:
print(f"捕获到自定义异常: {e.message}")
在这个例子中,CustomError
是一个自定义异常,可以通过 raise
关键字手动抛出并捕获。
7. raise
关键字
raise
关键字用于手动引发异常:
def check_age(age):
if age < 18:
raise ValueError("年龄必须大于或等于 18")
return True
try:
check_age(16)
except ValueError as e:
print(e)
在这个例子中,check_age()
函数如果接收到小于 18 的年龄,会抛出 ValueError
异常。
8. 断言(assert
)
assert
语句用于测试表达式的正确性,如果表达式为 False
,则会引发 AssertionError
异常:
def divide(a, b):
assert b != 0, "除数不能为零"
return a / b
print(divide(10, 2)) # 正常执行
print(divide(10, 0)) # 引发 AssertionError: 除数不能为零
9.异常类型
1. BaseException 类
- 所有异常的基类。
2. 常见异常类型
系统退出和中断
SystemExit
: 解释器请求退出。KeyboardInterrupt
: 用户中断执行,通常是按Ctrl+C
。GeneratorExit
: 生成器(generator)退出时抛出的异常。
标准异常
Exception
: 常规异常的基类。StopIteration
: 迭代器没有更多项时抛出。StopAsyncIteration
: 异步迭代器没有更多项时抛出。
逻辑错误
-
ArithmeticError
: 所有数值计算错误的基类。FloatingPointError
: 浮点运算错误。OverflowError
: 数值运算导致结果超出范围。ZeroDivisionError
: 除数为零。
-
AssertionError
: 断言语句失败时抛出(assert
)。 -
AttributeError
: 尝试访问不存在的对象属性。 -
BufferError
: 与缓冲区相关的操作引发的问题。 -
EOFError
: 遇到文件结束符(EOF),而没有读取到足够数据时抛出。 -
ImportError
: 模块导入失败时抛出。ModuleNotFoundError
: 找不到模块时引发的异常(ImportError
的子类)。
-
LookupError
: 无效查找操作的基类。IndexError
: 序列索引超出范围。KeyError
: 字典中找不到指定的键。
-
MemoryError
: 内存不足时抛出。 -
NameError
: 访问未定义的变量。UnboundLocalError
: 访问局部变量前未绑定值(NameError
的子类)。
-
OSError
: 操作系统错误的基类。-
BlockingIOError
: 操作会阻塞(例如非阻塞操作不能立即完成)。 -
ChildProcessError
: 子进程相关的错误。 -
ConnectionError
: 与连接相关的错误。BrokenPipeError
: 管道破裂错误。ConnectionAbortedError
: 连接中止错误。ConnectionRefusedError
: 连接被拒绝错误。ConnectionResetError
: 连接被重置错误。
-
FileExistsError
: 尝试创建文件或目录时,文件或目录已存在。 -
FileNotFoundError
: 尝试访问不存在的文件或目录。 -
InterruptedError
: 系统调用被中断。 -
IsADirectoryError
: 文件操作目标是一个目录,但要求的是文件。 -
NotADirectoryError
: 文件操作目标不是目录,但要求的是目录。 -
PermissionError
: 没有执行操作的权限。 -
ProcessLookupError
: 无法找到指定的进程。 -
TimeoutError
: 操作超时。
-
I/O错误
IOError
: 输入/输出操作失败的基类(在 Python 3 中是OSError
的别名)。
运行时错误
RuntimeError
: 一般的运行时错误。NotImplementedError
: 未实现的方法。RecursionError
: 递归层次过深。
类型错误
-
TypeError
: 操作或函数应用于不适当的类型。 -
ValueError
: 函数接收到具有正确类型但不适合的值。UnicodeError
: Unicode 相关的错误(ValueError
的子类)。UnicodeDecodeError
: 解码过程中发生错误。UnicodeEncodeError
: 编码过程中发生错误。UnicodeTranslateError
: 转换过程中发生错误。
编码错误
EncodingError
: 字符串编码/解码的错误。
系统相关错误
SystemError
: 解释器内部发生错误,但不严重。ReferenceError
: 弱引用(weakref
)尝试访问已垃圾回收的对象。OverflowError
: 算术操作导致数值超出表示范围。MemoryError
: 内存不足时引发的异常。
警告类异常
Warning
: 警告的基类。UserWarning
: 用户代码生成的警告。DeprecationWarning
: 与已弃用功能相关的警告。SyntaxWarning
: 与语法相关的警告。RuntimeWarning
: 与运行时情况相关的警告。FutureWarning
: 关于未来语义更改的警告。
语法错误
SyntaxError
: Python 语法错误。IndentationError
: 缩进错误。TabError
: 不一致的制表符和空格缩进。
总结
Python 的异常处理机制通过 try-except-else-finally
结构,使得程序可以优雅地处理各种可能的错误情况。通过捕获特定异常、捕获所有异常、自定义异常和使用 raise
关键字,你可以让你的程序在错误情况下依然保持稳定,并输出有用的错误信息。