如何为复杂对象编写自定义JSON解码器?

前端之家收集整理的这篇文章主要介绍了如何为复杂对象编写自定义JSON解码器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
就像标题所说的那样,我正在尝试为我已定义的类包含其他类我定义的对象的对象编写自定义解码器. “外部”类是Edge,定义如下:
class Edge:
    def __init__(self,actor,movie):
        self.actor = actor
        self.movie = movie

    def __eq__(self,other):
        if (self.movie == other.movie) & (self.actor == other.actor):
            return True
        else:
            return False

    def __str__(self):
        print("Actor: ",self.actor," Movie: ",self.movie)

    def get_actor(self):
        return self.actor

    def get_movie(self):
        return self.movie

与“内部”类的actor和电影定义如下:

class Movie:
    def __init__(self,title,gross,soup,year):
        self.title = title
        self.gross = gross
        self.soup = soup
        self.year = year

    def __eq__(self,other):
        if self.title == other.title:
            return True
        else:
            return False

    def __repr__(self):
        return self.title

    def __str__(self):
        return self.title

    def get_gross(self):
        return self.gross

    def get_soup(self):
        return self.soup

    def get_title(self):
        return self.title

    def get_year(self):
        return self.year

class Actor:
    def __init__(self,name,age,soup):
        self.name = name
        self.age = age
        self.soup = soup

    def __eq__(self,other):
        if self.name == other.name:
            return True
        else:
            return False

    def __repr__(self):
        return self.name

    def __str__(self):
        return self.name

    def get_age(self):
        return self.age

    def get_name(self):
        return self.name

    def get_soup(self):
        return self.soup

(汤只是该电影/演员的维基百科页面的美丽对象,它可以被忽略).
我也为边缘类编写了一个客户编码器:

class EdgeEncoder(json.JSONEncoder):
    def default(self,o):
        if isinstance(o,Edge):
            return {
                    "Actor": {
                             "Name": o.get_actor().get_name(),"Age": o.get_actor().get_age()
                             },"Movie": {
                             "Title": o.get_movie().get_title(),"Gross": o.get_movie().get_gross(),"Year": o.get_movie().get_year()
                             }
                    }
        return json.JSONEncoder.default(self,o)

我已经测试过,它正确地将边缘列表序列化为JSON文件.现在我的问题出现在尝试编写边缘解码器时.我使用了github页面here作为参考,但我的编码器偏离了他,我想知道是否有必要改变它.我是否需要在其JSON序列化中将对象的类型显式编码为其自己的键值对,或者是否有某种方法可以通过边缘的序列化来获取“Actor”和“Movie”键?同样,有没有办法获取名称”. “Age”等,这样我可以重建Actor / Movie对象,然后使用它们重建边缘?有没有更好的方法来编码我的对象?我也尝试过遵循this教程,但我发现对象dicts的使用让他们的编码器感到困惑,我不知道如何将该方法扩展到包含自定义对象的自定义对象.

解决方法

您引用的编码器/解码器示例( here)可以轻松扩展,以允许JSON输入/输出中的不同类型的对象.

但是,如果您只想要一个简单的解码器来匹配您的编码器(只在您的JSON文件中编码Edge对象),请使用此解码器:

class EdgeDecoder(json.JSONDecoder):
    def __init__(self,*args,**kwargs):
        json.JSONDecoder.__init__(self,object_hook=self.object_hook,**kwargs)
    def object_hook(self,dct):
        if 'Actor' in dct:
            actor = Actor(dct['Actor']['Name'],dct['Actor']['Age'],'')
            movie = Movie(dct['Movie']['Title'],dct['Movie']['Gross'],'',dct['Movie']['Year'])
            return Edge(actor,movie)
        return dct

使用问题中的代码定义类Movie,Actor,Edge和EdgeEncoder,以下代码输出一个测试文件,然后将其读回:

filename='test.json'
movie = Movie('Python','many dollars','2000')
actor = Actor('Casper Van Dien',49,'')
edge = Edge(actor,movie)
with open(filename,'w') as jsonfile:
    json.dump(edge,jsonfile,cls=EdgeEncoder)
with open(filename,'r') as jsonfile:
    edge1 = json.load(jsonfile,cls=EdgeDecoder)
assert edge1 == edge

猜你在找的JavaScript相关文章