尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python 字符串转对象的多种解法——从 JSON 到 Document 对象
在 Python 开发中我们经常遇到字符串看起来像某种数据结构list、dict、对象但实际类型却是str的情况。如何安全、高效地将这些字符串还原为真正的 Python 对象本文通过两道实战题目带你掌握 5 种核心解法。题目一JSON 字符串转列表题目描述给定一个 JSON 格式的字符串将其转换为 Python 列表raw_str[qwen-turbo,qwen-plus,deepseek]解法一json.loads()推荐 ⭐⭐⭐⭐⭐importjson raw_str[qwen-turbo,qwen-plus,deepseek]resultjson.loads(raw_str)print(result)# [qwen-turbo, qwen-plus, deepseek]print(type(result))# class listprint(type(result[0]))# class str优点标准库内置无需额外安装安全可靠不会执行恶意代码支持 JSON 所有数据类型str、int、float、bool、list、dict、null适用场景数据来自 API 接口、配置文件、数据库等标准 JSON 格式。解法二ast.literal_eval()推荐 ⭐⭐⭐⭐importast raw_str[qwen-turbo,qwen-plus,deepseek]resultast.literal_eval(raw_str)print(result)# [qwen-turbo, qwen-plus, deepseek]print(type(result))# class list优点支持更广泛的 Python 字面量tuple、set、frozenset、bytes、complex比eval()安全只解析字面量不执行函数调用缺点比json.loads()稍慢不支持 JSON 特有的null、true、falsePython 中对应None、True、False适用场景字符串是 Python 语法格式如单引号、元组、集合等而非严格 JSON。解法三eval()不推荐 ❌raw_str[qwen-turbo,qwen-plus,deepseek]resulteval(raw_str)print(result)# [qwen-turbo, qwen-plus, deepseek]严重安全隐患# 如果字符串来自用户输入可能包含恶意代码malicious_str__import__(os).system(rm -rf /)eval(malicious_str)# 执行系统命令数据全删结论永远不要对不可信输入使用eval()解法四正则表达式提取兜底方案importre raw_str[qwen-turbo,qwen-plus,deepseek]# 提取引号内的内容resultre.findall(r([^]),raw_str)print(result)# [qwen-turbo, qwen-plus, deepseek]适用场景字符串格式不规范不是标准 JSON但需要提取部分内容。缺点无法处理嵌套结构如 list 里包含 dict。解法五字符串替换 split最原始raw_str[qwen-turbo,qwen-plus,deepseek]# 去掉首尾方括号去掉引号按逗号分割resultraw_str.strip([]).replace(,).split(,)print(result)# [qwen-turbo, qwen-plus, deepseek]缺点极易出错无法处理包含逗号或引号的元素。仅适用于最简单、格式完全可控的场景。第一题解法对比总结解法安全性速度适用场景推荐度json.loads()高快标准 JSON⭐⭐⭐⭐⭐ast.literal_eval()高中Python 字面量⭐⭐⭐⭐eval()极低快绝不使用❌正则表达式中中非标准格式⭐⭐字符串操作高快极简场景⭐题目二Document 对象 repr 字符串解析题目描述给定一个字符串其中包含多个Document对象的 repr 表示需要提取所有Document对象获取每个Document的page_content按page排序后拼接raw_documents[Document(metadata{pk: 12, page: 2}, page_content第一章...), Document(metadata{pk: 27, page: 2}, page_content第二章...), Document(metadata{pk: 14, page: 3}, page_content第三章...)]核心难点这不是标准 JSON而是 Python 对象的repr()输出包含单引号字符串类名Document(...)嵌套的metadata字典换行符\n解法一正则表达式提取推荐 ⭐⭐⭐⭐importrefromdataclassesimportdataclassdataclassclassDocument:metadata:dictpage_content:strraw_documents[Document(metadata{pk: 12, page: 2}, page_content第一章内容...), Document(metadata{pk: 27, page: 2}, page_content第二章内容...), Document(metadata{pk: 14, page: 3}, page_content第三章内容...)]defparse_documents_regex(raw_str):使用正则表达式提取 Document 对象documents[]# 匹配 Document(...) 的内容patternrDocument\(metadata\{([^}])\},\s*page_content([^])\)matchesre.findall(pattern,raw_str)formetadata_str,contentinmatches:# 解析 metadata 字典meta{}forpairinmetadata_str.split(,):key,valuepair.strip().split(:)keykey.strip().strip()valueint(value.strip())meta[key]value documents.append(Document(metadatameta,page_contentcontent))returndocuments# 解析docsparse_documents_regex(raw_documents)# 按 page 排序sorted_docssorted(docs,keylambdad:d.metadata[page])# 拼接 page_contentfull_text\n\n.join([doc.page_contentfordocinsorted_docs])print(full_text)优点不依赖外部库安全可控只提取需要的数据缺点正则表达式脆弱格式稍有变化就失效需要手动处理嵌套结构解法二ast.literal_eval() 自定义解析 ⭐⭐⭐⭐⭐importast raw_documents[Document(metadata{pk: 12, page: 2}, page_content第一章内容...), Document(metadata{pk: 27, page: 2}, page_content第二章内容...)]# 步骤 1将 Document(...) 替换为普通字典# 让字符串看起来像 Python 字面量defdocument_to_dict_str(raw_str):将 Document 对象转换为字典格式的字符串importre# 去掉最外层的方括号innerraw_str.strip([])# 分割多个 Documentpartsre.split(r\),\s*Document\(,inner)# 处理首尾parts[0]parts[0].replace(Document(,{)parts[-1]parts[-1].replace(),})foriinrange(1,len(parts)-1):parts[i]{parts[i]# 重新组合为列表dict_str[}, {.join(parts)]returndict_str# 步骤 2使用 ast.literal_eval 安全解析dict_strdocument_to_dict_str(raw_documents)parsedast.literal_eval(dict_str)print(parsed)# [{metadata: {pk: 12, page: 2}, page_content: 第一章内容...}, ...]优点利用ast.literal_eval的安全性比纯正则更健壮缺点需要预处理字符串格式复杂的嵌套结构处理麻烦解法三模拟 Document 类 eval()仅用于学习# 定义 Document 类classDocument:def__init__(self,metadata,page_content):self.metadatametadata self.page_contentpage_contentdef__repr__(self):returnfDocument(metadata{self.metadata}, page_content{self.page_content[:20]}...)raw_documents[Document(metadata{pk: 12, page: 2}, page_content第一章...), ...]# 在受控环境中使用 eval# ⚠️ 仅用于学习生产环境绝对不要对不可信输入使用resulteval(raw_documents,{__builtins__:{}},{Document:Document})print(result[0].page_content)警告此方法需要严格控制执行环境仅适用于完全可信的数据源。解法四如果原始数据源可用——直接从源头解决最佳实践如果这些数据来自某个数据库或 API应该直接从源头获取结构化数据而不是解析 repr 字符串。# 理想情况直接从数据库/ORM 获取fromsqlalchemy.ormimportSessiondefget_documents_from_db(session:Session):从数据库直接查询 Document 对象documentssession.query(Document).order_by(Document.page).all()returndocuments# 拼接text\n\n.join([doc.page_contentfordocindocuments])核心原则repr 字符串是显示给人看的不是给程序解析的。如果可能永远使用原始数据源。第二题完整解决方案importrefromdataclassesimportdataclassfromtypingimportListdataclassclassDocument:metadata:dictpage_content:strdefparse_documents(raw_str:str)-List[Document]: 解析 Document repr 字符串 提取所有 Document 对象获取 page_content 并拼接 documents[]# 匹配 Document(...) 结构patternrDocument\(metadata(\{[^}]\}),\s*page_content((?:[^\\]|\\.)*?)\)matchesre.finditer(pattern,raw_str)formatchinmatches:metadata_strmatch.group(1)page_contentmatch.group(2)# 解析 metadata 字典metadataast.literal_eval(metadata_str)# 处理转义字符page_contentpage_content.replace(\\n,\n)documents.append(Document(metadatametadata,page_contentpage_content))returndocumentsdefmerge_documents(documents:List[Document])-str:按 page 排序并拼接# 按 page 排序sorted_docssorted(documents,keylambdad:d.metadata.get(page,0))# 拼接return\n\n.join([doc.page_contentfordocinsorted_docs])# 完整示例 raw_documents[Document(metadata{pk: 12, page: 2}, page_content2. 费用报销业务活动中产生的费用须凭真实、合规的发票并写明事由经审批后方可报销。严禁虚报、谎报费用。\n第五章 奖惩制度\n第13条 奖励\n对于符合下列条件的员工公司将视情况给予通报表扬、奖金、晋升等奖励\n1. 超额完成销售指标业绩突出者。\n2. 提出合理化建议经采纳后为公司带来显著效益者。\n3. 在维护公司利益和声誉方面有重大贡献者。), Document(metadata{pk: 27, page: 2}, page_content2. 费用报销业务活动中产生的费用须凭真实、合规的发票并写明事由经审批后方可报销。严禁虚报、谎报费用。\n第五章 奖惩制度\n第13条 奖励\n对于符合下列条件的员工公司将视情况给予通报表扬、奖金、晋升等奖励\n1. 超额完成销售指标业绩突出者。\n2. 提出合理化建议经采纳后为公司带来显著效益者。\n3. 在维护公司利益和声誉方面有重大贡献者。), Document(metadata{pk: 14, page: 3}, page_content3. 最后警告情节严重留司察看。\n4. 立即解雇对于严重违纪者公司有权单方面无条件解除劳动合同无需支付经济补偿金。严重违纪包括但不限于\n贪污、受贿、泄露核心商业秘密。\n虚报业绩、伪造销售记录或报销凭证。\n长期旷工连续三天或月累计五天。\n严重失职给公司造成重大经济损失或声誉损害。\n违反国家法律法规被依法追究刑事责任。\n第六章 附则\n第15条 守则的修订与解释)] # 解析docsparse_documents(raw_documents)print(f解析出{len(docs)}个 Document)# 查看fordocindocs:print(f\nPage{doc.metadata[page]}:{doc.page_content[:50]}...)# 拼接full_textmerge_documents(docs)print(f\n\n{*50})print(拼接结果前200字)print(full_text[:200])核心总结安全转换优先级1. json.loads() ← 标准 JSON首选 2. ast.literal_eval() ← Python 字面量安全 3. 数据源直接获取 ← 最理想避免解析字符串 4. 正则表达式 ← 格式不规范时的兜底 5. eval() ← 绝不用于不可信输入关键原则原则说明安全优先永远不要对不可信输入使用eval()标准优先优先使用json.loads()处理标准 JSON源头优先可能的话从原始数据源获取结构化数据验证输出转换后验证类型和内容是否符合预期异常处理用 try-except 包裹解析代码异常处理模板importjsondefsafe_parse_json(raw_str):安全解析 JSON 字符串try:resultjson.loads(raw_str)ifnotisinstance(result,list):raiseValueError(f期望 list得到{type(result)})returnresultexceptjson.JSONDecodeErrorase:print(fJSON 解析失败{e})return[]exceptExceptionase:print(f未知错误{e})return[]# 使用raw_str[qwen-turbo,qwen-plus,deepseek]resultsafe_parse_json(raw_str)实战练习尝试解析以下字符串# 练习 1嵌套 JSONtest1{models: [{name: GPT-4, provider: OpenAI}, {name: Claude, provider: Anthropic}]}# 练习 2混合引号test2[{\id\: 1, \name\: Alice}, {\id\: 2, \name\: Bob}]# 练习 3包含特殊字符test3[Hello\\nWorld, Tab\\tHere, Quote\\\Test\]如果这篇文章对你有帮助欢迎点赞、收藏、关注你的支持是我持续创作的动力。
RELATED

相关推荐

AI Agent平台核心中间件设计:从沙盒安全到可观测性实战

AI Agent平台核心中间件设计:从沙盒安全到可观测性实战

1. 项目概述:为什么中间件是Agent平台的“神经系统”如果你正在搭建或研究一个AI Agent平台,无论是想复现DeerFlow这样的成熟项目,还是从零开始设计自己的框架,那么“中间件”这个概念,绝对是你绕不开、且必须吃透的核…

📅 2026/9/24 7:41:54
分享一个免费3D看图审图工具,不用装UG/SW真的太方便了

分享一个免费3D看图审图工具,不用装UG/SW真的太方便了

干模具、CNC、3D打印的兄弟们,应该都被3D图纸整破防过吧?客户发的STEP、STL文件,电脑没装软件直接打不开;装个CAD又卡又占内存,版本不对还兼容报错;外出、手机根本没法看图,对接客户超级麻烦。给…

📅 2026/10/5 16:41:33
Linux设备驱动模型:从kobject到platform_driver的完整解析

Linux设备驱动模型:从kobject到platform_driver的完整解析

1. 项目概述:从“裸奔”到“有组织”的进化 搞过一段时间Linux驱动开发的朋友,大概都经历过这么一个阶段:写一个最简单的字符设备驱动, insmod 加载, mknod 创建设备节点,然后写个测试程序去 open 、…

📅 2026/10/6 2:56:17
MORE NEWS

更多资讯

📰

Midway 参数校验(Validation)组件实战指南:DTO 校验、校验管道与多验证器扩展

后端微服务云原生 【免费下载链接】midway 🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate w…

📰

免费解锁 WeMod 专业版:Wand-Enhancer 本地补丁 + 手机远程面板全流程

免费解锁 WeMod 专业版:Wand-Enhancer 本地补丁 手机远程面板全流程 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer WeMod 免费版广告…

📰

k0s 上安装 MetalLB 负载均衡器:为裸金属集群提供 Service LoadBalancer 的完整实践指南

云原生容器编排边缘计算 【免费下载链接】k0s k0s - The Zero Friction Kubernetes 项目地址: https://gitcode.com/gh_mirrors/k0/k0s 点击查看 免费下载 k0s 默认不内置负载均衡器,要为 Kubernetes Service 提供 LoadBalancer 类型支持,Me…

📰

Sunshine 游戏串流主机:把客厅大屏变成游戏厅的完整上手指南

Sunshine 游戏串流主机:把客厅大屏变成游戏厅的完整上手指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你手里那台显卡很能打的串流主机,平时可能一天…

📰

Visual Studio Code 外观焕新实战:Color Theme、File Icon Theme 与字体连字(Font Ligatures)完整指南

文档教程 【免费下载链接】vscode-docs Public documentation for Visual Studio Code 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-docs 点击查看 免费下载 导读 对全职开发者而言,一款赏心悦目的编辑器与编码能力同等重要——每天大量时间停…

📰

合伙人管理软件系统研发:流量资本化与权益分配机制拆解

做管理软件研发这些年,我发现一个很有意思的现象:大部分合伙人制度死在“软件太简单”上。你以为签个协议、开个账户、按比例分红就完事了,但真正做起来才发现,最难的往往不是分钱,而是怎么定义“流量贡献”&#xff0…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬