我目前在Python中有两个这样的类
class person:
age=""
name=""
ranking = {}
def addRanking():
#Do Whatever treatment and add to the ranking dict
class ranking:
semester = ""
position = ""
gpa = ""
我有一个名为dictP
json.dumps()
的字典,但似乎没有用。这是我转储到JSON的函数
def toJson():
jsonfile = open('dict.json', 'w')
print(json.dump(listP, jsonfile))
我很有名:不是JSON可序列化的。
您知道我可以做些什么来解决这个问题。我认为拥有两个可序列化的字典可以避免这种问题,但显然不会。
预先感谢
编辑:
这里有个例子(抱歉,我在手机上打错了打字,我不确定它是否可以运行,但是您可以理解)
class person:
age=""
name=""
ranking = {}
def __init__(self, age, name):
self.age = age
self.name = name
self.ranking = {}
def addRanking(self,semester,position,gpa):
#if the semester is not already present in the data for that person
self.ranking[semester] = make_ranking(semester,position,gpa)
class ranking:
semester = ""
position = ""
gpa = ""
def __init__(self, semester, position, gpa):
self.semester = semester
self.position = position
self.gpa = gpa
dictP = {}
def make_person(age, name):
# Some stuff happens there
return person(age,name)
def make_ranking(semester,postion,gpa):
#some computation there
return ranking(semester,position,gpa)
def pretending_to_read_csv():
age = 12
name = "Alice"
p = make_person(age, name)
dictP["1"] = p
age = 13
name = "Alice"
p = make_person(age, name)
dictP["2"] = p
#We read a csv for ranking that gives us an ID
semester = 1
position = 4
gpa = 3.2
id = 1
dictP["1"].addRanking(semester, position, gpa)
semester = 2
position = 4
gpa = 3.2
id = 1
dictP["1"].addRanking(semester, position, gpa)
答案 0 :(得分:1)
您可以尝试在实例的json.dump
成员上调用.__dict__
。您说您有一个人员实例列表,因此请尝试执行以下操作:
listJSON = []
for p in listP
#append the value of the dictionary containing data about your person instance to a list
listJSON.append(p.__dict__)
json.dump(listJSON, jsonfile)
如果您将个人实例存储在字典中,例如:dictP = {'person1': p1, 'person2': p2}
,则此解决方案将遍历键并将其对应的值更改为实例的__dict__
成员:
for key in dictP:
dictP[key] = dictP[key].__dict__
json.dump(dictP, jsonfile)
答案 1 :(得分:1)
要使字典可序列化,请注意,该字典中的所有键和值也必须可序列化。您没有向我们展示listP
包含的内容,但我猜是这样的:
>>> listP
[<__main__.person instance at 0x107b65290>, <__main__.person instance at 0x107b65368>]
Python实例不可序列化。
我认为您想要一个字典列表,如下所示:
>>> listP
[{'ranking': {}, 'age': 10, 'name': 'fred'}, {'ranking': {}, 'age': 20, 'name': 'mary'}]
这将按您的预期进行序列化:
>>> import json
>>> json.dumps(listP)
'[{"ranking": {}, "age": 10, "name": "fred"}, {"ranking": {}, "age": 20, "name": "mary"}]'
更新
(感谢添加示例代码。)
>>> pretending_to_read_csv()
>>> dictP
{'1': <__main__.person instance at 0x107b65368>, '2': <__main__.person instance at 0x107b863b0>}
回想一下,用户定义的类不能自动序列化。可以直接扩展JSONEncoder
来处理这些情况,但是您真正需要的只是一个函数,它可以将您的对象变成一个完全由基元组成的字典。
def convert_ranking(ranking):
return {
"semester": ranking.semester,
"position": ranking.position,
"gpa": ranking.gpa}
def convert_person(person):
return {
"age": person.age,
"name": person.name,
"ranking": {semester: convert_ranking(ranking) for semester, ranking in person.ranking.iteritems()}}
再进行一次字典理解即可真正完成转换,一切就绪:
>>> new_dict = {person_id: convert_person(person) for person_id, person in dictP.iteritems()}
>>> from pprint import pprint
>>> pprint(new_dict)
{'1': {'age': 12,
'name': 'Alice',
'ranking': {1: {'gpa': 3.2, 'position': 4, 'semester': 1},
2: {'gpa': 3.2, 'position': 4, 'semester': 2}}},
'2': {'age': 13, 'name': 'Alice', 'ranking': {}}}
由于其中没有填充用户定义的对象,因此将按您希望的那样进行序列化:
>>> json.dumps(new_dict)
'{"1": {"ranking": {"1": {"position": 4, "semester": 1, "gpa": 3.2}, "2": {"position": 4, "semester": 2, "gpa": 3.2}}, "age": 12, "name": "Alice"}, "2": {"ranking": {}, "age": 13, "name": "Alice"}}'