如何将Python对象写入JSON文件?

时间:2018-04-25 12:48:59

标签: python json

我的课程中有三个课程,

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文件?

3 个答案:

答案 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))

其中fileContentsprocessArray

获取返回的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个保存文件夹中。