Python中将自定义对象列表正确转换为JSON并保存至文件的最佳方案
解决自定义对象列表转JSON并正确保存的问题
你的问题出在每次循环单独把单个对象的字典dump到文件里,这样生成的内容是多个独立的JSON对象,而合法的JSON文档只能有一个顶级元素(要么是数组,要么是单个对象),所以解析器会报错。
下面是几种正确的实现方式,按推荐程度排序:
方法1:一次性转换整个列表为字典列表并保存(推荐)
先把所有BountyItem对象转成字典,组成一个列表,然后一次性用json.dump写入文件,这样会自动生成合法的JSON数组格式:
import json import requests from bs4 import BeautifulSoup list1 = [] class BountyItem: def __init__(self, heading, price, tickets): self.heading = heading self.price = price self.tickets = tickets url = 'https://www.bountycompetitions.co.uk/live-competitions/' page = requests.get(url) soup = BeautifulSoup(page.content, 'html.parser') result = soup.find_all(class_='product') for item in result: item_heading = item.find('a', attrs={'class': 'product-item-heading'}) item_price = item.find('span', attrs={'class': 'woocommerce-Price-amount amount'}) item_tickets = item.find('span', attrs={'class': 'status'}) # 直接创建对象加入列表即可,无需重复实例化 b_item = BountyItem(item_heading.text, item_price.text[1:], item_tickets.text) list1.append(b_item) # 将对象列表转换为字典列表 dict_list = [item.__dict__ for item in list1] # 一次性写入整个合法的JSON数组 with open("/home/pr0xibus/Documents/test.txt", 'w') as file: json.dump(dict_list, file, indent=4) # indent=4用于格式化输出,可选
生成的合法JSON内容示例:
[ { "heading": "Highland Park – Valhalla Collection – Odin 16 year old Whisky", "price": "1.20", "tickets": "249 Left" }, { "heading": "Tom Ford Rose Prick Collection", "price": "0.99", "tickets": "189 Left" } ]
方法2:自定义JSON编码器(更优雅的对象转JSON方式)
如果不想手动调用__dict__,可以自定义一个JSON编码器,这样直接dump对象列表也能正确转换:
# 自定义编码器 class BountyItemEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, BountyItem): return obj.__dict__ # 其他类型交给默认逻辑处理 return super().default(obj) # 保存时指定编码器 with open("/home/pr0xibus/Documents/test.txt", 'w') as file: json.dump(list1, file, cls=BountyItemEncoder, indent=4)
这种方式更适合后续扩展(比如对象有需要特殊处理的属性时),代码可读性也更强。
为什么原来的方法不合法?
你之前的代码每次循环打开文件追加写入单个JSON对象,最终文件内容是多个独立的{...}块,既没有用[]包裹成数组,也没有用逗号分隔。而JSON规范要求整个文档只能有一个顶级值,所以这种内容无法被标准JSON解析器正确解析。
内容的提问来源于stack exchange,提问作者pr0xibus
相关产品推荐
相关产品推荐

