异常处理与断言机制
异常处理是编程中非常重要的一个环节,用于捕获和处理程序运行过程中可能发生的错误。下面将详细介绍异常的定义、分类以及处理方法。
什么是异常
异常是指在程序执行过程中出现的非正常情况,通常会导致程序中断。它与错误不同:
- 错误(Error):一般指语法或逻辑上的问题,编译阶段即可检测到。
- 异常(Exception):运行时发生的问题,例如除以零、访问不存在的索引等。
查看异常信息
当异常发生时,Python会提供详细的报错信息。我们可以通过try-except结构来捕获并查看这些信息。
简单异常处理
以下是一个简单的异常处理示例:
data = ['a', 'b', 'c']
for index, value in enumerate(data, start=1):
print(index, value)
try:
user_input = int(input("请输入数字: "))
print(data[user_input - 1])
except ValueError:
print("请确保输入的是整数")
except IndexError:
print("输入的数字超出了范围")
此代码可以有效处理ValueError和IndexError。
万能异常
如果需要捕获所有类型的异常,可以使用Exception作为通用异常类型:
try:
dictionary = {}
dictionary["nonexistent_key"]
except Exception as e:
print(f"捕获到异常: {type(e).__name__}, 内容: {e}")
通过这种方式,我们可以获取异常的具体类型和描述信息。
多分支异常处理
可以结合多个except块来分别处理不同类型的异常:
try:
undefined_variable
empty_list = []
empty_list[0]
except NameError:
print("变量未定义")
except IndexError:
print("列表索引超出范围")
except Exception:
print("其他未知异常")
注意,Exception应始终放在最后,以避免掩盖前面的特定异常。
其他异常处理机制
try-except
可以同时捕获多种异常:
try:
undefined_variable
empty_list = []
empty_list[0]
except (NameError, IndexError) as e:
print(f"发生异常: {e}")
try-except-else
如果没有异常发生,则执行else块:
try:
result = 10 / 2
except ZeroDivisionError:
print("不能除以零")
else:
print(f"计算结果为: {result}")
try-except-finally
无论是否发生异常,finally块都会执行,常用于资源回收:
try:
file = open("example.txt", "r")
content = file.read()
except FileNotFoundError:
print("文件未找到")
finally:
if 'file' in locals():
file.close()
print("文件已关闭")
即使函数提前返回,finally仍然会被执行:
def example_function():
try:
return "操作完成"
finally:
print("执行清理操作")
result = example_function()
print(result)
输出结果为:
执行清理操作
操作完成
主动抛出异常
可以使用raise关键字手动触发异常:
try:
number = int(input("请输入一个整数: "))
if number < 0:
raise ValueError("输入的数字不能为负")
except ValueError as e:
print(f"错误: {e}")
自定义异常
还可以创建自定义异常类:
class CustomError(Exception):
def __init__(self, message):
self.message = message
try:
raise CustomError("这是一个自定义错误")
except CustomError as e:
print(f"捕获到自定义异常: {e.message}")
这里的CustomError继承自Exception,也可以直接继承BaseException。
断言机制
断言是一种调试工具,用于验证条件是否成立。如果条件为假,则抛出AssertionError:
value = True
assert value, "断言失败"
# 等价于
if not value:
raise AssertionError("断言失败")
断言的优点在于简洁,无需额外缩进。
注意事项
- 异常处理主要用于开发和调试阶段,不适合向最终用户提供提示。
assert语句在优化模式下会被忽略,因此不应依赖其进行关键逻辑验证。