本文目录导读:

在Python中,异常规避(Exception Avoidance)的核心思想是“先检查,后操作”(Look Before You Leap, LBYL),而不是“事后处理”**(Easier to Ask for Forgiveness than Permission, EAFP),以下是一些常见的异常规避案例及其预防方法:
文件操作异常
❌ 容易报错的做法
# 直接打开文件,如果不存在会报错
file = open('data.txt', 'r')
content = file.read()
✅ 异常规避方案
import os
# 方法1:检查文件是否存在
if os.path.exists('data.txt') and os.path.isfile('data.txt'):
with open('data.txt', 'r') as file:
content = file.read()
else:
print("文件不存在或不是文件")
# 方法2:使用 pathlib(推荐)
from pathlib import Path
file_path = Path('data.txt')
if file_path.is_file():
content = file_path.read_text()
else:
print("文件不存在")
字典键访问异常
❌ 容易报错的做法
user = {'name': 'Tom', 'age': 25}
# 如果键不存在会报 KeyError
email = user['email']
✅ 异常规避方案
user = {'name': 'Tom', 'age': 25}
# 方法1:使用 get() 方法
email = user.get('email', 'default@email.com') # 返回默认值
# 方法2:使用 setdefault() 方法
email = user.setdefault('email', 'default@email.com') # 不存在则设置默认值
# 方法3:使用 defaultdict
from collections import defaultdict
user_dict = defaultdict(lambda: 'default@email.com')
user_dict.update(user)
print(user_dict['email']) # 不会报错
列表/索引访问异常
❌ 容易报错的做法
numbers = [1, 2, 3] # 如果索引超出范围会报 IndexError value = numbers[5]
✅ 异常规避方案
numbers = [1, 2, 3]
# 方法1:检查索引范围
def safe_get(lst, index, default=None):
if 0 <= index < len(lst):
return lst[index]
return default
value = safe_get(numbers, 5, 'not found')
# 方法2:使用切片(不会报错)
value = numbers[5:6] # 返回空列表 []
value = numbers[5:6] or 'not found'
除法运算异常
❌ 容易报错的做法
# 除数为零会报 ZeroDivisionError result = 10 / 0
✅ 异常规避方案
# 方法1:检查除数
def safe_divide(a, b):
if b != 0:
return a / b
return float('inf') # 或返回其他默认值
# 方法2:使用 Decimal 类型
from decimal import Decimal, DivisionByZero
try:
result = Decimal(10) / Decimal(0)
except DivisionByZero:
result = Decimal('Infinity')
类型转换异常
❌ 容易报错的做法
# 字符串无法转换为整数会报 ValueError
number = int("abc")
✅ 异常规避方案
# 方法1:使用字符串方法检查
def safe_int(value, default=0):
if isinstance(value, str) and value.strip().isdigit():
return int(value)
if isinstance(value, (int, float)):
return int(value)
return default
# 方法2:使用正则表达式
import re
def safe_int_regex(value, default=0):
if re.match(r'^[+-]?\d+$', str(value)):
return int(value)
return default
网络请求异常
❌ 容易报错的做法
import requests
# 网络异常或服务器错误会报异常
response = requests.get('https://example.com')
✅ 异常规避方案
import requests
from requests.exceptions import RequestException
def safe_request(url, timeout=5):
# 先检查 URL 格式
if not url.startswith(('http://', 'https://')):
print("无效的URL格式")
return None
try:
response = requests.get(url, timeout=timeout)
response.raise_for_status() # 检查 HTTP 状态码
return response.json()
except RequestException as e:
print(f"请求失败: {e}")
return None
except ValueError as e:
print(f"JSON解析失败: {e}")
return None
属性访问异常
❌ 容易报错的做法
class User:
def __init__(self, name):
self.name = name
user = User('Tom')
# 如果属性不存在会报 AttributeError
email = user.email
✅ 异常规避方案
# 方法1:使用 hasattr() 检查
user = User('Tom')
if hasattr(user, 'email'):
email = user.email
else:
email = 'default@email.com'
# 方法2:使用 getattr() 方法
email = getattr(user, 'email', 'default@email.com')
# 方法3:使用 __getattribute__ 自定义
class SafeUser:
def __init__(self, name):
self.name = name
self._defaults = {'email': 'default@email.com'}
def __getattribute__(self, name):
try:
return super().__getattribute__(name)
except AttributeError:
defaults = super().__getattribute__('_defaults')
return defaults.get(name, f"属性'{name}'不存在")
数据库操作异常
❌ 容易报错的做法
import sqlite3
conn = sqlite3.connect('database.db')
# 如果表不存在会报错
cursor = conn.execute("SELECT * FROM users")
✅ 异常规避方案
import sqlite3
from sqlite3 import OperationalError
def safe_query(database, query, params=None):
try:
conn = sqlite3.connect(database)
if params:
cursor = conn.execute(query, params)
else:
cursor = conn.execute(query)
# 获取字段名
columns = [description[0] for description in cursor.description]
result = [dict(zip(columns, row)) for row in cursor.fetchall()]
conn.close()
return result
except OperationalError as e:
print(f"数据库操作错误: {e}")
return []
except Exception as e:
print(f"未知错误: {e}")
return []
- 优先使用LBYL:在可能出错的地方提前检查
- 使用类型注解:减少类型相关的错误
- 提供默认值:使用
get(),setdefault(),getattr()等方法 - 使用守卫语句(Guard Clause):尽早返回或处理异常情况
- 验证输入:在处理外部数据前进行验证
# 综合示例
def process_user_data(data: dict) -> dict:
"""安全的用户数据处理函数"""
# 守卫语句:检查数据类型
if not isinstance(data, dict):
return {'error': '无效的数据格式'}
# 使用get方法获取默认值
return {
'name': data.get('name', 'Unknown'),
'age': int(data.get('age', 0)) if str(data.get('age', '')).isdigit() else 0,
'email': data.get('email', 'no_email@example.com'),
'status': 'active' if data.get('status') == 1 else 'inactive'
}
通过这种方式,你可以有效减少Python程序中的异常,提高代码的健壮性和可维护性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播