错误与异常处理
程序在运行过程中不可避免地会遇到错误。Python 提供了强大的异常处理机制,不仅能防止程序崩溃,还能通过捕获错误来进行补救。
1. 错误类型
语法错误 (Syntax Errors)
代码不符合 Python 语法规则,程序根本无法启动。
# SyntaxError: unterminated string literal
print("Hello)
异常 (Exceptions)
语法正确,但在运行时发生的错误。如果不处理,程序会中断。
# ZeroDivisionError: division by zero
10 / 0
# FileNotFoundError
open("no_exist.txt")
2. 捕获异常 (try-except)
基本结构
try:
# 可能发生异常的代码
num = int(input("请输入数字: "))
result = 100 / num
print(f"结果是: {result}")
except ValueError:
# 捕获输入非数字的情况
print("错误:请输入有效的数字!")
except ZeroDivisionError:
# 捕获除以零的情况
print("错误:不能除以零!")
except Exception as e:
# 捕获所有其他类型的异常 (兜底)
print(f"发生未知错误: {e}")
最佳实践
尽量捕获具体的异常类型,而不是泛泛地捕获所有异常 (Exception),这样方便调试和定位问题。
3. 完整的异常结构 (try-except-else-finally)
try:
f = open("data.txt", "r")
content = f.read()
except FileNotFoundError:
print("文件未找到")
else:
# 只有 try 块没有异常时才执行
print("读取成功,内容长度:", len(content))
finally:
#无论是否有异常,都会执行 (常用于资源清理)
print("关闭文件资源")
if 'f' in locals():
f.close()
4. 抛出异常 (raise)
有时我们需要主动触发错误,通知调用者出现了问题。
def check_age(age):
if age < 0:
raise ValueError("年龄不能为负数")
if age > 150:
raise ValueError("年龄超出合理范围")
print(f"年龄 {age} 验证通过")
try:
check_age(-5)
except ValueError as e:
print(f"验证失败: {e}")
5. 自定义异常
通过继承 Exception 类来定义业务相关的异常。
class InsufficientFundsError(Exception):
"""余额不足异常"""
pass
def withdraw(amount, balance):
if amount > balance:
raise InsufficientFundsError(f"余额不足: 需 {amount}, 只有 {balance}")
return balance - amount
try:
withdraw(100, 50)
except InsufficientFundsError as e:
print(e)
常见内置异常清单
| 异常名 | 描述 |
|---|---|
IndexError |
列表索引超出范围 |
KeyError |
字典中找不到键 |
TypeError |
操作类型不匹配 (如 str + int) |
ValueError |
参数值不对 |
AttributeError |
对象没有该属性或方法 |
ImportError |
导入模块失败 |
调试建议 (Debugging)
- 阅读 Traceback: 报错信息并不吓人,它会明确告诉你错误在哪一行以及是什么错误。
- 使用 print 调试: 在关键位置打印变量值。
- IDE 断点调试: 在 VS Code 中直接打断点 (F9/F5) 逐行执行,是最最高效的方法。
本章小结
- try: 放置可能出错的代码。
- except: 捕获并处理特定错误。
- else: 若无异常发生时执行。
- finally: 无论如何都执行(清理善后)。
- raise: 主动抛出异常。
练习题
- 安全除法:编写一个函数
safe_div(a, b),返回a / b。如果b为 0,不报错而是返回None。 - 输入验证:循环提示用户输入数字,直到输入正确的数字为止。如果输入非数字,打印提示并继续循环。
下一章:面向对象编程基础