VWED_server/utils/json_parser.py

105 lines
3.5 KiB
Python
Raw Normal View History

2025-09-25 10:52:52 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
通用JSON/字典解析工具
"""
import json
from typing import Any, Dict, Optional
from utils.logger import get_logger
logger = get_logger("json_parser")
def safe_parse_json(param: str, script_id: Optional[str] = None, default_return: Any = None) -> Any:
"""安全解析JSON或Python字典格式的字符串
尝试多种解析方式:
1. 首先尝试标准JSON解析
2. 如果JSON解析失败尝试使用eval解析Python字典格式
Args:
param: 要解析的字符串
script_id: 脚本ID用于日志记录
default_return: 解析失败时的默认返回值
Returns:
解析后的数据失败时返回default_return
"""
if not isinstance(param, str):
if script_id:
logger.error(f"脚本 {script_id} 输入参数不是字符串类型: {type(param)}")
else:
logger.error(f"输入参数不是字符串类型: {type(param)}")
return default_return
# 1. 首先尝试标准JSON解析
try:
data = json.loads(param)
return data
except json.JSONDecodeError:
# 2. 如果JSON解析失败尝试使用eval解析Python字典或列表格式
try:
# 安全地使用eval解析字典或列表字符串
stripped_param = param.strip()
if (stripped_param.startswith('{') and stripped_param.endswith('}')) or \
(stripped_param.startswith('[') and stripped_param.endswith(']')):
data = eval(param, {"__builtins__": {}}, {})
return data
else:
if script_id:
logger.error(f"脚本 {script_id} 参数格式不正确: {param}")
else:
logger.error(f"参数格式不正确: {param}")
return default_return
except Exception as eval_error:
if script_id:
logger.error(f"脚本 {script_id} 参数解析失败: {str(eval_error)}, 参数: {param}")
else:
logger.error(f"参数解析失败: {str(eval_error)}, 参数: {param}")
return default_return
def safe_parse_dict(param: str, script_id: Optional[str] = None) -> Optional[Dict[str, Any]]:
"""安全解析为字典类型
Args:
param: 要解析的字符串
script_id: 脚本ID用于日志记录
Returns:
解析后的字典失败时返回None
"""
data = safe_parse_json(param, script_id, None)
if not isinstance(data, dict):
if script_id:
logger.error(f"脚本 {script_id} 参数格式错误,期望字典类型: {type(data)}")
else:
logger.error(f"参数格式错误,期望字典类型: {type(data)}")
return None
return data
def safe_parse_list(param: str, script_id: Optional[str] = None) -> Optional[list]:
"""安全解析为列表类型
Args:
param: 要解析的字符串
script_id: 脚本ID用于日志记录
Returns:
解析后的列表失败时返回None
"""
data = safe_parse_json(param, script_id, None)
if not isinstance(data, list):
if script_id:
logger.error(f"脚本 {script_id} 参数格式错误,期望列表类型: {type(data)}")
else:
logger.error(f"参数格式错误,期望列表类型: {type(data)}")
return None
return data