Python生成JSON时字符串意外被包裹为列表的问题排查
问题描述
使用Python的json模块为JavaScript程序生成测试数据时,数值类型数据能正常输出"name": value格式,但字符串类型数据却被意外包裹为"name": ["value"]的列表形式,需要修复该问题。
代码
import json import random import uuid entry_template = { "itemId": None, "date": None, "subjectAreas": None, "images": None, "title": None, "description": None, "method": None, "materials": None, "size": {"width": None, "height": None, "depth": None}, "weight": None } subjectAreas = [ ["drawings"], ["prints"], ["watercolor"], ["automata"], ["art3d"], ["art3d", "automata"], ] titles = [ "Spring chicken", "Black nignt", "Red sunset", ] descriptions = [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sit amet arcu vitae ipsum luctus elementum. Aliquam vel tortor mi. Sed venenatis turpis justo, sit amet rhoncus magna dictum ac. Sed eget iaculis mi. Pellentesque habitant morbi.", "Pellentesque sollicitudin diam ac urna aliquet auctor. Nulla vel nisl lacus. Vestibulum eget vestibulum massa. Nulla blandit nec augue lacinia lobortis. Morbi lacus ipsum, aliquet sit amet volutpat at, pellentesque eget mauris. Nunc ullamcorper pulvinar ex, id accumsan orci hendrerit non. Etiam rhoncus eros a nulla fermentum iaculis. ", ] methods = [ "Pencil drawing", "print", ] materials = [ "wood", "watercolor on paper", ] def sometimes(x): return random.randint(0, 12) > x def gen_dimension(): return random.randint(200, 500) def select_val(list_name): return list_name[random.randint(0, len(list_name) - 1)] def gen_id(): return str(uuid.uuid4()) def gen_date_string(): year = random.randint(1990, 2024) month = random.randint(1, 12) day = random.randint(1, 28) hour = random.randint(0, 23) minutes = random.randint(0, 59) seconds = random.randint(0, 59) return f"{year}-{month:02}-{day:02} {hour:02}:{minutes:02}:{seconds:02}" images = ["10000", "10001", "10002", "10003"] image_range = [1, 1, 1, 1, 1, 2, 2, 3] def gen_image_ids(): image_key = select_val(images) image_names = [image_key] for num in range(1, image_range[random.randint(0, len(image_range) - 1)]): image_names.append(f'{image_key}-{num}') return image_names entries = [] for num in range(0, 2): entry = entry_template.copy() entry["itemId"] = gen_id(), entry["date"] = gen_date_string(), entry["subjectAreas"] = select_val(subjectAreas), entry["images"] = gen_image_ids(), entry["title"] = select_val(titles), entry["description"] = select_val(descriptions), entry["method"] = select_val(methods), entry["materials"] = select_val(materials), entry["size"] = {"width": gen_dimension(), "height": gen_dimension(), "depth": gen_dimension()}, entry["weight"] = gen_dimension() # print(json.dumps(entry, indent=4)) entries.append(entry) entries_json = json.dumps(entries, indent=4) entries_json = "const galleryItems = " + entries_json + "\n\nexport default galleryItems;\n" print(entries_json) # with open("gallery.js", "w") as file: # file.write(entries_json)
实际输出
const galleryItems = [ { "itemId": [ "42198f4d-c69d-4fa6-8146-6b08c6237240" ], "date": [ "2011-08-11 22:41:09" ], "subjectAreas": [ [ "workshops" ] ], "images": [ [ "10002" ] ], "title": [ "Black nignt" ], "description": [ "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet." ], "method": [ "Mechanical device" ], "materials": [ "watercolor on paper" ], "size": [ { "width": 272, "height": 206, "depth": 365 } ], "weight": 450 }, { "itemId": [ "f2f1c977-5e8a-469e-b6ea-e946a0aa9e68" ], "date": [ "1991-01-25 01:04:48" ], "subjectAreas": [ [ "automata" ] ], "images": [ [ "10001", "10001-1" ] ], "title": [ "Black nignt" ], "description": [ "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet." ], "method": [ "Pencil drawing" ], "materials": [ "Oilbased inks on paper" ], "size": [ { "width": 380, "height": 214, "depth": 385 } ], "weight": 448 } ] export default galleryItems;
期望输出
const galleryItems = [ { "itemId": "42198f4d-c69d-4fa6-8146-6b08c6237240", "date": "2011-08-11 22:41:09", "subjectAreas": ["workshops"], "images": ["10002"], "title": "Black nignt", "description": "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet.", "method": "Mechanical device", "materials": "watercolor on paper", "size": { "width": 272, "height": 206, "depth": 365 }, "weight": 450 }, { "itemId": "f2f1c977-5e8a-469e-b6ea-e946a0aa9e68", "date": "1991-01-25 01:04:48", "subjectAreas": ["automata"], "images": ["10001","10001-1"], "title": "Black nignt", "description": "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet.", "method": "Pencil drawing", "materials": "Oilbased inks on paper", "size": { "width": 380, "height": 214, "depth": 385 }, "weight": 448 } ]
解决方案
问题根源是赋值语句末尾的逗号:在Python中,单个值后面加逗号会被解析为元组(比如gen_id(),实际是一个包含唯一ID字符串的元组),而json模块序列化元组时会将其转换为数组。
只需删除循环中以下赋值行末尾的逗号即可:
entry["itemId"] = gen_id(),→entry["itemId"] = gen_id()entry["date"] = gen_date_string(),→entry["date"] = gen_date_string()entry["subjectAreas"] = select_val(subjectAreas),→entry["subjectAreas"] = select_val(subjectAreas)entry["images"] = gen_image_ids(),→entry["images"] = gen_image_ids()entry["title"] = select_val(titles),→entry["title"] = select_val(titles)entry["description"] = select_val(descriptions),→entry["description"] = select_val(descriptions)entry["method"] = select_val(methods),→entry["method"] = select_val(methods)entry["materials"] = select_val(materials),→entry["materials"] = select_val(materials)entry["size"] = {"width": gen_dimension(), "height": gen_dimension(), "depth": gen_dimension()},→entry["size"] = {"width": gen_dimension(), "height": gen_dimension(), "depth": gen_dimension()}
修改后的循环代码片段:
for num in range(0, 2): entry = entry_template.copy() entry["itemId"] = gen_id() entry["date"] = gen_date_string() entry["subjectAreas"] = select_val(subjectAreas) entry["images"] = gen_image_ids() entry["title"] = select_val(titles) entry["description"] = select_val(descriptions) entry["method"] = select_val(methods) entry["materials"] = select_val(materials) entry["size"] = {"width": gen_dimension(), "height": gen_dimension(), "depth": gen_dimension()} entry["weight"] = gen_dimension() entries.append(entry)
运行修改后的代码,就能生成符合期望格式的JSON数据。
内容的提问来源于stack exchange,提问作者Andy Gleeson
相关产品推荐
相关产品推荐

