我的课程中有三个课程,
Processes
包含Lanes
。
Lanes
包含Tasks
。
对象作为数组相互存储,并带有关于类
的其他字符串信息我正在尝试将Process对象输出到JSON文件中,但我不断收到以下错误:
Object of type 'Process' is not JSON serializable
我是JSON处理的新手,所以我不明白为什么对象输出这个错误。
我正在使用以下代码将Process
个对象打印为JSON项目:
def outputJSON(self):
for n in self.processes:
print(json.dumps(n, sort_keys=True, indent=4))
这些是类对象:
class Task(object):
def __init__(self, name, UiD):
self.name = name
self.UiD = UiD
self.incoming = 'None'
self.outgoing = []
self.messageFlowIn = 'None'
self.messageFlowOut = 'None'
def __str__(self):
print(self.name +"\n")
print("Incoming Connection : \n" + self.incoming + "\n")
print("Outgoing Connections : ")
if len(self.outgoing) >= 1:
for n in self.outgoing:
print(n+"\n")
print("MessageFlowIn : " + self.messageFlowIn)
print("MessageFlowOut : " + self.messageFlowOut)
class Lane(object):
def __init__(self, name, associatedTasks):
self.name = name
self.associatedTasks = associatedTasks
class Process(object):
def __init__(self, name, associatedLaneNames):
self.name = name
self.associatedLaneNames = associatedLaneNames
self.laneObjects = []
如何正确地将此数据输出到JSON文件?
答案 0 :(得分:1)
假设您的属性是简单值或列表,您可以使用类getElementsByClassName
属性将类转换为dict,然后将其序列化为json,例如:
.__dict__
输出:
p = Process('name', 'lanename')
p.laneObjects.extend([Lane('name', [Task('name', 'uid')])])
def to_dict(obj):
output ={}
for key, item in obj.__dict__.items():
if isinstance(item, list):
l = []
for item in item:
d = to_dict(item)
l.append(d)
output[key] = l
else:
output[key] = item
return output
to_dict(p)
作为一个词典。
答案 1 :(得分:0)
关注@czr的例子;解决方案是通过并将对象映射转换为显式字典,然后输出这些嵌套字典的数组,如下所示:
def serialize(self):
processArray =[]
decisionItems = []
for process in self.processes:
processObj = {}
laneArray = []
for lane in process.laneObjects:
laneObj = {}
taskArray = []
for task in lane.associatedTasks:
taskObj = {}
for variableName, value in task.__dict__.items():
temp = value
placeHolderArray =[]
if isinstance(value, Task) or isinstance(value, StartEvent) or isinstance(value, EndEvent):
temp = value.name
taskObj[variableName] = temp
elif isinstance(value,list): #fix these lines
for n in value:
if isinstance(n, Task) or isinstance(n, StartEvent) or isinstance(n, EndEvent) or isinstance(n, DecisionBranch):
placeHolderArray.append(n.name)
taskObj[variableName] = placeHolderArray
elif isinstance(value, DecisionBranch):
taskObj['junctionPath'] = task.junctionPath
decisionBranch = {}
decisionBranch['name'] = value.name
decisionBranch['options'] = value.decisionBranch
decisionBranch['source'] = value.source
#taskObj['DecisionTree'] = decisionBranch
taskObj['URLs'] = task.urls
taskArray.append(taskObj)
laneObj['name'] = lane.name
laneObj['associatedTasks'] = taskArray
laneArray.append(laneObj)
processObj['name'] = process.name
processObj['laneObjects'] = laneArray
processArray.append(processObj)
return processArray
def outputJsonFile(self, fileContents):
tempString = self.fileName.split('.')
outputName = tempString[0]+'.json'
with open(outputName, 'w') as outfile:
outfile.write(json.dumps(fileContents, sort_keys=True, indent=4))
其中fileContents
从processArray
serialize()
需要注意的是,按如下方式迭代类变量:
for variableName, value in objectName.__dict__.items():
允许您将类变量及其各自的值检索为字典。由于您是我上面的代码,如果碰巧您的值是一个对象,那么您必须使用python方便isinstance()
显式定义要从该对象检索的属性:
if isinstance(value, Task) or isinstance(value, StartEvent) or isinstance(value, EndEvent):
temp = value.name
taskObj[variableName] = temp
如果是python经典对象,例如list;确保明确地迭代它:
elif isinstance(value,list): #fix these lines
for n in value:
if isinstance(n, Task) or isinstance(n, StartEvent) or isinstance(n, EndEvent) or isinstance(n, DecisionBranch):
placeHolderArray.append(n.name)
taskObj[variableName] = placeHolderArray
我最初混淆的原因是我之前使用google GSON
获取Java的经验。这个方便的api只需要一个Java类,并为您轻松输出一个JSON格式的文件。不幸的是,Python没有这样的本机库。理想的解决方案是以各种方式设计类,使它们只包含本机数据类型,如字符串,整数或本机数据类型列表。这样简单地迭代objectName.__dict__.item()
将为您提供一个足够的解决方案。
答案 2 :(得分:-1)
尝试使用pickle序列化并写入.JSON https://docs.python.org/3/library/pickle.html
以下是我如何为使用泡菜的游戏保存数据的示例
def save():
file_player = "Save/%s/player.JSON" % functions.player.name
file_world = "Save/%s/world.JSON" % functions.player.name
file_counter = "Save/%s/counter.JSON" % functions.player.name
a = functions.player
b = world.world_map
c = functions.counter
save_player = open(file_player, 'wb')
save_world = open(file_world, 'wb')
save_counter = open(file_counter, 'wb')
pickle.dump(a, save_player, -1)
pickle.dump(b, save_world, -1)
pickle.dump(c, save_counter, -1)
save_player.close()
save_world.close()
save_counter.close()
这将从3个不同的文件中保存3个不同的类,并将它们转储到1个保存文件夹中。