本文目录导读:

我来系统地介绍Python中异常处理的几种方式和最佳实践。
基础异常处理
try-except 基本结构
# 基本用法
try:
num = int(input("请输入一个数字: "))
result = 10 / num
print(f"结果是: {result}")
except ValueError:
print("输入的不是有效数字")
except ZeroDivisionError:
print("不能除以零")
多个异常处理
try:
data = [1, 2, 3]
index = int(input("请输入索引: "))
print(data[index])
except (ValueError, IndexError) as e:
print(f"发生错误: {e}")
完整的异常处理结构
try-except-else-finally
def divide_numbers(a, b):
try:
result = a / b
except ZeroDivisionError:
print("除数不能为零")
return None
except TypeError:
print("参数类型错误")
return None
else:
# 没有异常时执行
print(f"计算成功: {result}")
return result
finally:
# 无论是否异常都会执行
print(f"本次计算完成,参数: {a}, {b}")
# 测试
print(divide_numbers(10, 2))
print(divide_numbers(10, 0))
实际应用案例
案例1:文件操作异常处理
def read_file_safely(filename):
"""安全读取文件内容的函数"""
try:
with open(filename, 'r', encoding='utf-8') as file:
content = file.read()
print(f"文件 {filename} 读取成功")
return content
except FileNotFoundError:
print(f"错误: 文件 {filename} 不存在")
return None
except PermissionError:
print(f"错误: 没有权限读取文件 {filename}")
return None
except UnicodeDecodeError:
print(f"错误: 文件编码格式不正确")
return None
except Exception as e:
print(f"未知错误: {e}")
return None
# 使用示例
content = read_file_safely("example.txt")
if content:
print("文件内容:", content[:100])
案例2:用户输入验证
def get_valid_input(prompt, input_type=str):
"""获取有效的用户输入"""
while True:
try:
user_input = input(prompt)
if input_type == int:
return int(user_input)
elif input_type == float:
return float(user_input)
else:
return user_input.strip()
except ValueError:
print(f"输入无效,请输入有效的{input_type.__name__}类型")
except KeyboardInterrupt:
print("\n用户取消输入")
return None
except Exception as e:
print(f"发生错误: {e}")
# 使用示例
age = get_valid_input("请输入年龄: ", int)
if age is not None:
print(f"您的年龄是: {age}")
案例3:网络请求异常处理
import requests
import time
from urllib.error import URLError
def fetch_url_with_retry(url, max_retries=3, timeout=5):
"""带重试机制的URL请求函数"""
retries = 0
while retries < max_retries:
try:
response = requests.get(url, timeout=timeout)
response.raise_for_status() # 检查HTTP状态码
print(f"请求成功,状态码: {response.status_code}")
return response.text
except requests.exceptions.Timeout:
retries += 1
print(f"请求超时,第{retries}次重试...")
time.sleep(2) # 等待后重试
except requests.exceptions.ConnectionError:
print(f"网络连接错误: {url}")
return None
except requests.exceptions.HTTPError as e:
print(f"HTTP错误: {e}")
if response.status_code == 404:
print("页面不存在")
elif response.status_code == 403:
print("无权限访问")
return None
except Exception as e:
print(f"未知错误: {e}")
return None
print("最大重试次数已达")
return None
# 使用示例
html = fetch_url_with_retry("https://example.com")
案例4:数据库操作异常处理
import sqlite3
class DatabaseManager:
"""数据库管理器,包含异常处理"""
def __init__(self, db_path):
self.db_path = db_path
self.connection = None
def connect(self):
try:
self.connection = sqlite3.connect(self.db_path)
print("数据库连接成功")
return True
except sqlite3.Error as e:
print(f"数据库连接失败: {e}")
return False
def execute_query(self, query, params=None):
try:
cursor = self.connection.cursor()
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
self.connection.commit()
return cursor
except sqlite3.IntegrityError as e:
print(f"数据完整性错误: {e}")
self.connection.rollback()
return None
except sqlite3.OperationalError as e:
print(f"数据库操作错误: {e}")
self.connection.rollback()
return None
except Exception as e:
print(f"未知错误: {e}")
self.connection.rollback()
return None
def close(self):
if self.connection:
try:
self.connection.close()
print("数据库连接已关闭")
except Exception as e:
print(f"关闭连接时出错: {e}")
# 使用示例
db = DatabaseManager("test.db")
if db.connect():
db.execute_query("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
db.execute_query("INSERT INTO users (name) VALUES (?)", ("张三",))
result = db.execute_query("SELECT * FROM users")
if result:
print("查询结果:", result.fetchall())
db.close()
自定义异常
class CustomError(Exception):
"""自定义异常类"""
def __init__(self, message, error_code=None):
super().__init__(message)
self.error_code = error_code
def validate_age(age):
if age < 0:
raise CustomError("年龄不能为负数", error_code=-1)
elif age > 150:
raise CustomError("年龄超出合理范围", error_code=-2)
return age
try:
user_age = validate_age(-5)
except CustomError as e:
print(f"自定义错误: {e}, 错误代码: {e.error_code}")
最佳实践
def best_practices_example():
"""异常处理最佳实践示例"""
# 1. 尽量具体而不是宽泛
try:
# 不好的做法
pass
except Exception: # 过于宽泛
pass
# 好的做法
try:
result = 10 / 2
except ZeroDivisionError:
print("除零错误")
except TypeError:
print("类型错误")
# 2. 使用上下文管理器处理资源
try:
with open('file.txt', 'r') as f:
content = f.read()
except FileNotFoundError:
print("文件不存在")
# 3. 记录异常信息
import logging
logging.basicConfig(level=logging.ERROR)
try:
risky_operation()
except Exception as e:
logging.error(f"操作失败: {e}", exc_info=True)
# 4. 不要忽略异常
try:
do_something()
except Exception:
pass # 避免这样做,至少要记录日志
def risky_operation():
raise ValueError("示例错误")
-
异常处理的基本原则:
- 只处理你知道如何处理的异常
- 尽量具体化异常类型
- 避免使用空的except子句
-
实际应用场景:
- 文件操作(文件不存在、权限问题)
- 网络请求(超时、连接错误)
- 数据库操作(连接失败、数据完整性)
- 用户输入验证(类型错误、范围错误)
-
好的异常处理可以让程序更健壮、更易维护。