Python异常简介
目录
一、异常的概念
1. 定义
2. 异常的作用
3. 异常的分类
(1)内置异常(Built-in Exceptions)
(2)自定义异常
二、捕获异常
1. 捕获指定异常
2. 捕获多个异常
3. 捕获所有异常
4. 捕获未知异常
三、 else和finally子句
1. else子句
2. finally子句
四、自定义异常
五、触发异常
六、异常的传递
一、异常的概念
1. 定义
异常(Exception)是程序执行过程中发生的错误或意外情况,可能导致程序终止。
错误类型
-
语法错误(SyntaxError):代码不符合Python语法规则(如拼写错误、缺少冒号等)。
-
运行时错误(RuntimeError):程序运行时因逻辑或外部环境导致的错误(如除零、文件不存在等)。
2. 异常的作用
-
避免程序崩溃,提供错误处理和恢复的机会。
-
通过
try-except
结构捕获并处理异常。
3. 异常的分类
(1)内置异常(Built-in Exceptions)
Python提供了大量内置异常类,常见类型如下:
异常类型 | 说明 | 示例 |
---|---|---|
Exception | 所有异常的基类 | 捕获通用异常 |
AssertionError | assert 语句失败时引发 | assert x > 0, "x must be positive" |
AttributeError | 对象没有该属性 | obj.nonexistent_attr |
FileNotFoundError | 文件不存在 | open('nonexistent.txt') |
IndexError | 索引越界 | list[100] |
KeyError | 字典键不存在 | dict['nonexistent_key'] |
NameError | 变量未定义 | print(undefined_var) |
TypeError | 操作或函数参数类型不匹配 | '2' + 3 |
ValueError | 参数值无效 | int('abc') |
ZeroDivisionError | 除以零 | 10 / 0 |
ImportError | 模块导入失败 | import nonexist_module |
(2)自定义异常
通过继承 Exception
或其子类创建自定义异常。
二、捕获异常
在程序运行过程中,不能因为遇到某些小异常就让整个程序彻底崩溃。 应该假设某处会出现异常,提前做好准备,当真的出现异常时可以处理异常。
1. 捕获指定异常
使用try
和except
关键字可以捕获并处理异常,在except
中可以指定要捕获的异常类型。基本语法如下:
try:
# 可能会引发异常的代码块
risky_operation()
except SomeException as e:
# 处理异常的代码块
handle_exception(e)
-
try
:包含可能引发异常的代码,一般只有一行。 -
except
:指定要捕获的异常类型,并处理该异常。如果代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。as e
允许将异常实例赋值给变量e
,以便在异常处理代码中使用。
2. 捕获多个异常
我们可以在一个except
块中捕获多个异常,只需将异常类型作为元组列出。
try:
risky_operation()
except (AttributeError, TypeError) as e:
handle_multiple_exceptions(e)
3. 捕获所有异常
使用 except
或 except Exception as e
可以捕获所有内建异常(不包括SystemExit
、KeyboardInterrupt
和GeneratorExit
),但不包括从BaseException
直接继承的其他异常。捕获所有异常应谨慎使用,因为它可能会隐藏程序中的真正问题。
try:
risky_operation()
except:
handle_all_exceptions(e)
try:
risky_operation()
except Exception as e:
handle_all_exceptions(e)
4. 捕获未知异常
使用 except BaseException as e
可以捕获所有异常,包括那些从BaseException
直接继承的异常。
try:
risky_operation()
except BaseException as e:
handle_unknown_exceptions(e)
三、 else
和finally
子句
1. else
子句
如果try
块中的代码没有引发异常,则执行else
块中的代码。
try:
risky_operation()
except SomeException as e:
handle_exception(e)
else:
if_no_exception_occurred()
2. finally
子句
无论是否发生异常,finally
块中的代码都会执行。常用于释放资源,如关闭文件或网络连接。
try:
risky_operation()
except SomeException as e:
handle_exception(e)
finally:
cleanup_operation()
四、自定义异常
我们可以通过继承 Exception
类来创建自定义异常类。
class MyCustomError(Exception):
def __init__(self, message, error_code):
super().__init__(message)
self.error_code = error_code
try:
raise MyCustomError("Something went wrong!", 404)
except MyCustomError as e:
print(f"Error: {e}, Code: {e.error_code}")
五、触发异常
使用raise
关键字可以手动触发异常。
if some_condition:
raise ValueError("Invalid value encountered!")
六、异常的传递
如果在try
块中发生异常,且没有在当前的 try-except
语句中被捕获,异常会被传递到上一层调用者。如果上层调用者也没有捕获异常,异常会继续向上传递,直到被捕获或导致程序崩溃。这种机制使得异常可以在合适的地方被处理。例如:
def divide(a, b):
try:
return a / b
except ZeroDivisionError as e:
print("在divide函数中捕获了除以零错误:", e)
raise # 重新抛出异常
def main():
try:
result = divide(1, 0)
except ZeroDivisionError as e:
print("在main函数中捕获了除以零错误:", e)
main()
在本例中,divide
函数捕获了 ZeroDivisionError
。