Python中如何将含datetime.date的字符串转为元组列表?
问题
客户端请求服务器后得到如下字符串响应:
x = "[(7, 'N°001C/MITP/CAB/UGP-BAD/2023 Du 30/01/2024', 'Recrutement d’une ONG/Firme pour les services d’accompagnement social,\r communication, sensibilisation des populations de la zone du projet d’Aménagement et de bitumage de la route\r Lola- Frontière de la Cote d’Ivoire', 'Sensibilisation', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 22), None, datetime.date(2024, 2, 5), 2), (9, 'N°001/MPFPV/PERSIF/UCP/2024', 'Mission d’audit des comptes du PERSIF. Exercices 2023 et 2024\r(l’audit de clôture inclus)', '', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 9), None, datetime.date(2024, 2, 5), 2)]"
需要将其转换为可直接使用的元组列表:
x = [(7, 'N°001C/MITP/CAB/UGP-BAD/2023 Du 30/01/2024', 'Recrutement d’une ONG/Firme pour les services d’accompagnement social,\r communication, sensibilisation des populations de la zone du projet d’Aménagement et de bitumage de la route\r Lola- Frontière de la Cote d’Ivoire', 'Sensibilisation', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 22), None, datetime.date(2024, 2, 5), 2), (9, 'N°001/MPFPV/PERSIF/UCP/2024', 'Mission d’audit des comptes du PERSIF. Exercices 2023 et 2024\r(l’audit de clôture inclus)', '', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 9), None, datetime.date(2024, 2, 5), 2)]
使用ast.literal_eval(x)无法完成转换,因为该方法不支持解析datetime.date对象。
解决方案
方法1:正则替换+安全解析+类型转换
这种方法规避eval的安全风险,通过正则标记日期对象,解析后再转换为datetime.date:
import ast import re from datetime import date # 原始服务器响应字符串 response_str = "[(7, 'N°001C/MITP/CAB/UGP-BAD/2023 Du 30/01/2024', 'Recrutement d’une ONG/Firme pour les services d’accompagnement social,\r communication, sensibilisation des populations de la zone du projet d’Aménagement et de bitumage de la route\r Lola- Frontière de la Cote d’Ivoire', 'Sensibilisation', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 22), None, datetime.date(2024, 2, 5), 2), (9, 'N°001/MPFPV/PERSIF/UCP/2024', 'Mission d’audit des comptes du PERSIF. Exercices 2023 et 2024\r(l’audit de clôture inclus)', '', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 9), None, datetime.date(2024, 2, 5), 2)]" # 将datetime.date(...)替换为带标记的元组 def replace_date_match(match): return f"('__DATE__', {match.group(1)})" processed_str = re.sub(r'datetime\.date\((\d+,\s*\d+,\s*\d+)\)', replace_date_match, response_str) # 用ast.literal_eval安全解析基础结构 parsed_data = ast.literal_eval(processed_str) # 递归转换标记元组为datetime.date对象 def convert_dates(data): if isinstance(data, tuple): return tuple(convert_dates(item) for item in data) elif isinstance(data, list): return [convert_dates(item) for item in data] elif isinstance(data, tuple) and len(data) == 2 and data[0] == '__DATE__': year, month, day = map(int, data[1].split(',')) return date(year, month, day) else: return data final_result = convert_dates(parsed_data)
方法2:使用eval(仅限可信来源)
如果能100%确认字符串来自安全可靠的服务器,可直接使用eval,但需提前导入datetime模块:
from datetime import datetime response_str = "[(7, 'N°001C/MITP/CAB/UGP-BAD/2023 Du 30/01/2024', 'Recrutement d’une ONG/Firme pour les services d’accompagnement social,\r communication, sensibilisation des populations de la zone du projet d’Aménagement et de bitumage de la route\r Lola- Frontière de la Cote d’Ivoire', 'Sensibilisation', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 22), None, datetime.date(2024, 2, 5), 2), (9, 'N°001/MPFPV/PERSIF/UCP/2024', 'Mission d’audit des comptes du PERSIF. Exercices 2023 et 2024\r(l’audit de clôture inclus)', '', 'Guinée', 'Qualité et Coût', '', datetime.date(2024, 2, 9), None, datetime.date(2024, 2, 5), 2)]" # 注意:仅当来源绝对可信时使用此方法 final_result = eval(response_str, {'datetime': datetime})
内容的提问来源于stack exchange,提问作者Borris Kouadja NIANGORAN
相关产品推荐
相关产品推荐

