异常处理
前言
异常处理是编写健壮程序的关键。本章介绍如何捕获和处理异常。
什么是异常
异常是在程序执行期间发生的错误。Python 使用异常对象表示错误。
# 可能引发异常的代码
result = 10 / 0 # ZeroDivisionError
try-except 语句
try:
# 可能引发异常的代码
result = 10 / 0
except ZeroDivisionError:
# 处理特定异常
print("Cannot divide by zero!")
捕获多个异常
try:
num = int(input("Enter a number: "))
result = 10 / num
except ValueError:
print("Invalid input! Please enter a number.")
except ZeroDivisionError:
print("Cannot divide by zero!")
except Exception as e:
print(f"An unexpected error occurred: {e}")
else 和 finally 子句
try:
file = open("example.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found")
else:
# 只有在没有异常时执行
print("File read successfully")
print(f"Content length: {len(content)}")
finally:
# 总是执行(无论是否异常)
if 'file' in locals():
file.close()
print("Cleanup completed")
抛出异常
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
try:
result = divide(10, 0)
except ValueError as e:
print(e)
自定义异常
class InsufficientFundsError(Exception):
"""自定义异常:余额不足"""
pass
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError("Insufficient funds")
self.balance -= amount
return amount
try:
account = BankAccount(100)
account.withdraw(150)
except InsufficientFundsError as e:
print(e)
异常层次结构
Python 异常形成层次结构:
- BaseException(所有异常的基类)
- Exception(常规异常)
- ValueError, TypeError, FileNotFoundError 等
- SystemExit, KeyboardInterrupt 等
- Exception(常规异常)
try:
# 一些代码
pass
except Exception:
# 捕获所有常规异常
print("An error occurred")
断言 (assert)
用于调试,确保条件为真。
def divide(a, b):
assert b != 0, "Cannot divide by zero"
return a / b
divide(10, 0) # AssertionError: Cannot divide by zero
日志记录
比 print 更好的错误记录方式。
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
try:
result = 10 / 0
except ZeroDivisionError:
logging.error("Division by zero attempted")
常见异常类型
ValueError: 值错误(如 int("abc"))TypeError: 类型错误(如 "hello" + 5)IndexError: 索引超出范围KeyError: 字典键不存在FileNotFoundError: 文件不存在ZeroDivisionError: 除零错误AttributeError: 属性不存在
最佳实践
- 只捕获你能处理的异常
- 保持异常处理简单
- 使用 finally 进行清理
- 提供有意义的错误信息
- 考虑使用日志而不是 print
本章小结
- 使用 try-except 捕获异常
- else 子句在无异常时执行,finally 总是执行
- 可以抛出和自定义异常
- 了解常见异常类型和最佳实践
练习题
- 编写一个函数,安全地进行除法运算,处理除零错误。
- 创建一个自定义异常类,并在一个函数中使用它。
- 编写一个程序,读取文件并处理可能的异常。
- 使用断言验证函数参数的有效性。
浙公网安备 33010602011771号