Python字符串转列表通用方法:从JSON到eval的安全实践
1. 引言在Python编程中我们经常会遇到需要将字符串表示的列表转换为实际列表对象的情况。比如从配置文件读取的字符串[qwen-turbo,qwen-plus,deepseek]或者包含对象实例的字符串[Person(Alice), Person(Bob)]。本文将详细介绍几种通用的转换方法并分析它们的适用场景和安全注意事项。2. 基础场景JSON格式字符串转列表2.1 使用json模块对于标准的JSON格式字符串json.loads()是最安全、最推荐的方法importjson# 示例1字符串列表raw_str[qwen-turbo,qwen-plus,deepseek]lsjson.loads(raw_str)print(ls)# [qwen-turbo, qwen-plus, deepseek]print(type(ls))# class list# 示例2嵌套列表nested_str[[a, b], [c, d]]nested_listjson.loads(nested_str)print(nested_list)# [[a, b], [c, d]]2.2 处理单引号问题JSON标准要求双引号但有时数据可能使用单引号。可以使用str.replace()预处理importjson raw_str[qwen-turbo,qwen-plus,deepseek]# 将单引号替换为双引号json_strraw_str.replace(,)lsjson.loads(json_str)print(ls)# [qwen-turbo, qwen-plus, deepseek]3. 进阶场景包含Python对象的字符串3.1 使用ast.literal_eval()当字符串包含Python字面量表达式时ast.literal_eval()比eval()更安全importast# 示例1基本列表raw_str[qwen-turbo, qwen-plus, deepseek]lsast.literal_eval(raw_str)print(ls)# [qwen-turbo, qwen-plus, deepseek]# 示例2数字列表num_str[1, 2, 3, 4, 5]num_listast.literal_eval(num_str)print(num_list)# [1, 2, 3, 4, 5]# 示例3混合类型mixed_str[1, hello, True, None]mixed_listast.literal_eval(mixed_str)print(mixed_list)# [1, hello, True, None]3.2 处理自定义对象实例对于包含对象实例的字符串需要更复杂的处理importastclassPerson:def__init__(self,name):self.namenamedef__repr__(self):returnfPerson({self.name})def__eq__(self,other):returnisinstance(other,Person)andself.nameother.name# 方法1使用eval仅限可信来源raw_str[Person(Alice), Person(Bob)]# 需要先定义Person类在当前作用域lseval(raw_str,{Person:Person})print(ls)# [Person(Alice), Person(Bob)]# 方法2安全解析并重建defparse_object_list(obj_str):安全解析对象列表字符串# 使用ast解析为ASTtreeast.parse(obj_str,modeeval)# 遍历AST节点提取构造信息objects[]fornodeinast.walk(tree):ifisinstance(node,ast.Call)andisinstance(node.func,ast.Name):ifnode.func.idPerson:# 提取参数args[]forarginnode.args:ifisinstance(arg,ast.Constant):args.append(arg.value)objects.append(Person(*args))returnobjects raw_str[Person(Alice), Person(Bob)]lsparse_object_list(raw_str)print(ls)# [Person(Alice), Person(Bob)]4. 通用转换函数4.1 智能转换函数下面是一个通用的智能转换函数可以处理多种格式importjsonimportastimportredefsmart_str_to_list(raw_str,safe_modeTrue): 将字符串转换为列表的通用函数 参数: raw_str: 输入字符串 safe_mode: 是否启用安全模式禁用eval 返回: 转换后的列表 # 去除首尾空白raw_strraw_str.strip()ifnotraw_str:return[]# 尝试JSON解析最安全try:# 处理单引号情况json_strraw_str.replace(,)returnjson.loads(json_str)exceptjson.JSONDecodeError:pass# 尝试ast.literal_eval相对安全try:returnast.literal_eval(raw_str)except(SyntaxError,ValueError):pass# 如果允许且必要尝试eval仅限可信数据ifnotsafe_mode:try:returneval(raw_str)except:pass# 最后尝试正则分割# 匹配引号内的内容或非空白字符patternr[\]([^\]*)[\]|([^,\s\[\]])matchesre.findall(pattern,raw_str)result[]formatchinmatches:# match[0]是引号内的内容match[1]是非引号内容itemmatch[0]ifmatch[0]elsematch[1]ifitem:# 尝试转换为数字try:if.initem:result.append(float(item))else:result.append(int(item))exceptValueError:result.append(item)returnresult# 测试各种格式test_cases[[qwen-turbo,qwen-plus,deepseek],[qwen-turbo,qwen-plus,deepseek],[1, 2, 3, 4, 5],[true, false, null],# JSON布尔值和null[a, b, c],apple, banana, cherry,]fortestintest_cases:resultsmart_str_to_list(test)print(f输入:{test})print(f输出:{result})print(f类型:{type(result)})print(-*40)4.2 带类型推断的转换defstr_to_list_with_types(raw_str): 将字符串转换为列表并自动推断元素类型 try:# 先尝试JSONresultjson.loads(raw_str.replace(,))except:try:# 再尝试literal_evalresultast.literal_eval(raw_str)except:# 最后使用简单分割result[item.strip()foriteminraw_str.strip([]).split(,)]# 类型推断和转换typed_result[]foriteminresult:ifisinstance(item,(int,float,bool,type(None))):typed_result.append(item)elifisinstance(item,str):# 尝试转换为数字try:if.initem:typed_result.append(float(item))else:typed_result.append(int(item))exceptValueError:# 尝试转换为布尔值ifitem.lower()true:typed_result.append(True)elifitem.lower()false:typed_result.append(False)elifitem.lower()nulloritem.lower()none:typed_result.append(None)else:typed_result.append(item)else:typed_result.append(item)returntyped_result# 测试test_str[1, 2.5, true, false, null, hello]resultstr_to_list_with_types(test_str)print(f输入:{test_str})print(f输出:{result})print(f类型:{[type(x)forxinresult]})5. 安全注意事项5.1 eval的安全风险# 危险示例永远不要对不可信数据使用evalmalicious_str__import__(os).system(rm -rf /)# 危险# result eval(malicious_str) # 千万不要执行# 安全替代方案defsafe_eval(expression,allowed_namesNone):受限的eval实现ifallowed_namesisNone:allowed_names{}# 编译时检查try:codecompile(expression,string,eval)exceptSyntaxError:raiseValueError(Invalid expression)# 检查允许的节点类型fornodeinast.walk(ast.parse(expression,modeeval)):ifisinstance(node,(ast.Import,ast.ImportFrom,ast.Call)):# 禁止导入和函数调用raiseValueError(Import and function calls are not allowed)returneval(code,{__builtins__:{}},allowed_names)5.2 最佳实践优先使用json.loads()处理JSON格式数据次选ast.literal_eval()处理Python字面量避免使用eval()除非完全控制数据来源验证输入数据使用白名单验证错误处理始终使用try-exceptdefsafe_str_to_list(raw_str,allowed_classesNone):安全地将字符串转换为列表ifallowed_classesisNone:allowed_classes{}# 输入验证ifnotisinstance(raw_str,str):raiseTypeError(Input must be a string)# 长度限制iflen(raw_str)10000:raiseValueError(Input string too long)try:# 尝试JSONreturnjson.loads(raw_str)exceptjson.JSONDecodeError:try:# 尝试literal_evalreturnast.literal_eval(raw_str)except(SyntaxError,ValueError):# 自定义对象处理受限ifallowed_classes:returneval(raw_str,{__builtins__:{}},allowed_classes)else:raiseValueError(Cannot safely parse the string)6. 实际应用示例6.1 配置文件解析importconfigparserimportjsonclassConfigLoader:def__init__(self,config_file):self.configconfigparser.ConfigParser()self.config.read(config_file)defget_list(self,section,key,defaultNone):从配置文件中获取列表try:valueself.config.get(section,key)returnsmart_str_to_list(value)except(configparser.NoSectionError,configparser.NoOptionError):returndefaultifdefaultisnotNoneelse[]# 配置文件内容示例# [models]# active_models [qwen-turbo, qwen-plus, deepseek]# batch_sizes [32, 64, 128]6.2 API响应处理importrequestsimportjsondefparse_api_response(response_text):解析API返回的字符串列表try:datajson.loads(response_text)# 如果API返回的是字符串形式的列表ifisinstance(data,dict)andmodelsindata:models_strdata[models]ifisinstance(models_str,str):returnsmart_str_to_list(models_str)returnmodels_strreturndataexceptjson.JSONDecodeError:# 尝试其他格式returnsmart_str_to_list(response_text)# 模拟API响应api_response{models: [\\qwen-turbo\\, \\qwen-plus\\, \\deepseek\\]}resultparse_api_response(api_response)print(f解析结果:{result})7. 性能比较importtimeitimportjsonimportast test_str[qwen-turbo,qwen-plus,deepseek,model-a,model-b]*100# 性能测试deftest_json():returnjson.loads(test_str)deftest_ast():returnast.literal_eval(test_str)deftest_eval():returneval(test_str)# 运行测试json_timetimeit.timeit(test_json,number1000)ast_timetimeit.timeit(test_ast,number1000)eval_timetimeit.timeit(test_eval,number1000)print(fjson.loads:{json_time:.6f}seconds)print(fast.literal_eval:{ast_time:.6f}seconds)print(feval:{eval_time:.6f}seconds)8. 总结本文介绍了多种将字符串转换为列表的方法json.loads()最安全适合JSON格式数据ast.literal_eval()相对安全适合Python字面量eval()功能最强但最危险仅限可信数据自定义解析函数灵活可控适合特定需求选择方法时需要考虑数据来源是否可信字符串格式是否规范是否需要处理自定义对象性能要求对于大多数场景推荐使用json.loads()或ast.literal_eval()避免使用eval()处理不可信数据。对于包含自定义对象的字符串建议使用安全的AST解析方法或限制eval的执行环境。

相关新闻

Unity游戏开发:工业级坐骑召唤系统设计与实现全解析

Unity游戏开发:工业级坐骑召唤系统设计与实现全解析

1. 项目概述:从需求到实现的完整拆解在游戏开发中,尤其是MMORPG、ARPG或者开放世界冒险类游戏里,“坐骑”系统几乎是标配。它不仅仅是玩家从一个点快速移动到另一个点的交通工具,更是角色成长、身份象征和游戏沉浸感的重要组成部分…

2026/10/13 7:55:25 阅读更多 →
WPF等待窗口开发:进度条+倒计时+监控一体化方案

WPF等待窗口开发:进度条+倒计时+监控一体化方案

1. WPF等待窗口开发实战:进度条倒计时监控功能一体化实现在桌面应用开发中,等待窗口是提升用户体验的关键组件。最近为一个工业监控项目开发了一套复合型等待窗口,整合了进度指示、倒计时提醒和后台任务监控三大功能。这种设计特别适合需要长…

2026/10/12 19:12:46 阅读更多 →
Unity中Ray Marching与Compute Shader实战:从原理到可扩展渲染框架

Unity中Ray Marching与Compute Shader实战:从原理到可扩展渲染框架

1. 项目概述:为什么要在Unity里折腾Ray Marching?如果你玩过《纪念碑谷》或者看过一些炫酷的科幻电影特效,里面那些扭曲、融合、无限重复的几何空间,是不是觉得特别酷?传统的3D建模和渲染管线,做这些效果要…

2026/10/9 10:29:44 阅读更多 →

最新新闻

SQL UNIQUE约束详解:原理、数据库差异与防重复设计实践

SQL UNIQUE约束详解:原理、数据库差异与防重复设计实践

1. UNIQUE约束到底是什么,为什么你需要它做数据库设计这些年,我见过太多因为“忘记加唯一约束”而崩溃的业务系统。最典型的场景:用户注册接口被脚本刷了一遍,username重复了;订单表里同一笔订单被回调程序insert了两次…

2026/10/13 7:55:19 阅读更多 →
Agent-Skills:智能体原子化能力的设计与工程实践

Agent-Skills:智能体原子化能力的设计与工程实践

1. “agent-skills”不是新词,而是智能体能力体系的命名共识 最近在多个技术社区、开源项目文档和内部架构评审会上,“agent-skills”这个组合词出现频率陡增——它既不指代某个具体开源库,也不是某家公司的私有协议,而是一类设计…

2026/10/13 7:55:19 阅读更多 →
Flink DataStream与Table API转换实战:Schema推导、时间属性与常见避坑指南

Flink DataStream与Table API转换实战:Schema推导、时间属性与常见避坑指南

做实时数据处理这几年,Flink的DataStream和Table API来回切换是我用得最频繁的操作之一。刚接触那会儿,总觉得这两套API是两套独立的体系,流上处理业务逻辑用DataStream,做统计查询用Table,中间隔着一道说不清的墙。后…

2026/10/13 7:55:19 阅读更多 →
LiteLLM:大模型API统一网关与智能路由实战指南

LiteLLM:大模型API统一网关与智能路由实战指南

1. LiteLLM不是另一个大模型,而是一把“万能适配器”最近在几个技术群和开源社区里,频繁看到有人发问:“LiteLLM到底是个啥?是又一个新模型吗?”“它和Ollama、LM Studio有什么区别?”——这种误解非常典型…

2026/10/13 7:55:19 阅读更多 →
LiteLLM:大模型API统一接入与智能路由实战指南

LiteLLM:大模型API统一接入与智能路由实战指南

1. 为什么“litellm”突然在开发者圈里被高频提及——它不是新模型,而是新范式最近两周,在多个技术社区、内部分享会和开源项目讨论区里,“litellm”这个词出现的频率明显升高。它不像Llama、Qwen或Claude那样代表一个具体的大语言模型&#…

2026/10/13 7:55:19 阅读更多 →
开源代码审查实战:流程设计、工具配置与团队落地方法

开源代码审查实战:流程设计、工具配置与团队落地方法

代码审查这事儿,我过去几年一直想好好聊一聊。初看上去,open-code-review 这个项目标题没什么特别,好像就是把自己团队做代码评审的过程、工具和规范整理出来,开源给社区用。但如果真这么理解,那就有点浪费了。代码审查…

2026/10/13 7:54:17 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →