backup materials and knowledge-base docs

This commit is contained in:
admin
2026-05-30 16:22:29 +08:00
commit 93e50e8fce
3024 changed files with 2994945 additions and 0 deletions

View File

@@ -0,0 +1,305 @@
"""
错误处理模式示例
展示各种错误处理的最佳实践
"""
import logging
from typing import Optional, List, Dict, Any
from functools import wraps
logger = logging.getLogger(__name__)
# ============================================
# 模式 1具体异常捕获
# ============================================
def read_file(filepath: str) -> Optional[str]:
"""
捕获具体异常而不是宽泛的 Exception
"""
try:
with open(filepath, 'r') as f:
return f.read()
except FileNotFoundError:
logger.error(f"文件不存在: {filepath}")
return None
except PermissionError:
logger.error(f"没有权限读取文件: {filepath}")
return None
except UnicodeDecodeError:
logger.error(f"文件编码错误: {filepath}")
return None
# ============================================
# 模式 2带重试的操作
# ============================================
def retry_operation(max_attempts: int = 3):
"""
装饰器:自动重试失败的操作
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
logger.error(f"操作失败,已重试 {max_attempts} 次: {e}")
raise
logger.warning(f"操作失败,第 {attempt} 次重试...")
return None
return wrapper
return decorator
@retry_operation(max_attempts=3)
def unstable_api_call() -> Dict[str, Any]:
"""
模拟不稳定的 API 调用
"""
import random
if random.random() < 0.7: # 70% 失败率
raise ConnectionError("API 连接失败")
return {"status": "success", "data": "result"}
# ============================================
# 模式 3上下文管理器处理资源
# ============================================
class DatabaseConnection:
"""
自定义上下文管理器,确保资源正确释放
"""
def __init__(self, connection_string: str):
self.connection_string = connection_string
self.connection = None
def __enter__(self):
logger.info(f"连接数据库: {self.connection_string}")
self.connection = f"Connection to {self.connection_string}"
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is not None:
logger.error(f"发生异常: {exc_val}")
logger.info("关闭数据库连接")
# 清理资源
self.connection = None
return False # 不抑制异常
# ============================================
# 模式 4链式异常保留原始异常
# ============================================
def validate_and_process(data: Dict[str, Any]) -> Any:
"""
使用 raise from 保留原始异常链
"""
try:
# 验证数据
if 'value' not in data:
raise ValueError("数据中缺少 'value' 字段")
value = data['value']
if not isinstance(value, (int, float)):
raise TypeError(f"value 应该是数字,实际类型: {type(value)}")
# 处理数据
return value * 2
except (ValueError, TypeError) as e:
# 保留原始异常并添加上下文
raise RuntimeError(f"数据处理失败: {data}") from e
# ============================================
# 模式 5结果对象模式不使用异常
# ============================================
class Result:
"""
结果对象模式:封装成功/失败状态
"""
def __init__(self, success: bool, value: Any = None, error: str = None):
self.success = success
self.value = value
self.error = error
@classmethod
def ok(cls, value: Any) -> 'Result':
return cls(success=True, value=value)
@classmethod
def err(cls, error: str) -> 'Result':
return cls(success=False, error=error)
def is_ok(self) -> bool:
return self.success
def is_err(self) -> bool:
return not self.success
def unwrap(self) -> Any:
if not self.success:
raise ValueError(f"尝试解包错误结果: {self.error}")
return self.value
def unwrap_or(self, default: Any) -> Any:
return self.value if self.success else default
def safe_divide_result(a: float, b: float) -> Result:
"""
使用结果对象而不是异常
"""
if b == 0:
return Result.err(f"除数不能为零: {b}")
try:
return Result.ok(a / b)
except Exception as e:
return Result.err(f"计算失败: {e}")
# ============================================
# 模式 6多项验证错误收集
# ============================================
class ValidationError(Exception):
"""自定义验证错误"""
def __init__(self, errors: List[str]):
self.errors = errors
super().__init__("\n".join(errors))
def validate_user(data: Dict[str, Any]) -> None:
"""
收集所有验证错误而不是遇到第一个就停止
"""
errors = []
if 'name' not in data:
errors.append("缺少 'name' 字段")
elif not isinstance(data['name'], str):
errors.append("'name' 应该是字符串")
elif len(data['name']) < 2:
errors.append("'name' 长度应该至少为 2")
if 'age' not in data:
errors.append("缺少 'age' 字段")
elif not isinstance(data['age'], int):
errors.append("'age' 应该是整数")
elif data['age'] < 0 or data['age'] > 150:
errors.append("'age' 应该在 0-150 之间")
if 'email' in data and '@' not in data['email']:
errors.append("'email' 格式不正确")
if errors:
raise ValidationError(errors)
# ============================================
# 模式 7默认值和回退
# ============================================
def get_config(config: Dict[str, Any], key: str, default: Any = None) -> Any:
"""
安全获取配置,支持多级键和默认值
"""
if '.' in key:
# 支持嵌套键,如 "database.host"
keys = key.split('.')
value = config
for k in keys:
if isinstance(value, dict) and k in value:
value = value[k]
else:
return default
return value
# 简单键
return config.get(key, default)
# ============================================
# 模式 8优雅降级
# ============================================
def get_user_preferences(user_id: int) -> Dict[str, Any]:
"""
尝试多种方法获取用户偏好,优雅降级
"""
# 尝试 1从缓存获取
try:
return _get_from_cache(user_id)
except Exception as e:
logger.warning(f"从缓存获取失败: {e}")
# 尝试 2从数据库获取
try:
return _get_from_database(user_id)
except Exception as e:
logger.warning(f"从数据库获取失败: {e}")
# 尝试 3使用默认配置
logger.info("使用默认配置")
return _get_default_preferences()
def _get_from_cache(user_id: int) -> Dict[str, Any]:
# 模拟缓存失败
raise ConnectionError("缓存连接失败")
def _get_from_database(user_id: int) -> Dict[str, Any]:
# 模拟数据库失败
raise ConnectionError("数据库连接失败")
def _get_default_preferences() -> Dict[str, Any]:
return {
"theme": "light",
"language": "zh-CN",
"notifications": True
}
# ============================================
# 测试代码
# ============================================
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
print("=" * 50)
print("错误处理模式示例")
print("=" * 50)
# 测试结果对象模式
print("\n1. 结果对象模式:")
result1 = safe_divide_result(10, 2)
print(f"10 / 2 = {result1.unwrap()}")
result2 = safe_divide_result(10, 0)
print(f"10 / 0 = {result2.unwrap_or('N/A')} ({result2.error})")
# 测试优雅降级
print("\n2. 优雅降级:")
prefs = get_user_preferences(123)
print(f"用户偏好: {prefs}")
# 测试上下文管理器
print("\n3. 上下文管理器:")
try:
with DatabaseConnection("localhost:5432") as conn:
print(f"连接: {conn}")
except Exception as e:
print(f"操作失败: {e}")