gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 01:11:44 29 4
gpt4 key购买 nike

就像标题所说,我正在尝试为一个我定义的类的对象编写一个自定义解码器,该对象包含我定义的类的其他对象。 “外部”类是一个 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

(汤只是该电影/ Actor 的维基百科页面的一个 beautifulsoup 对象,可以忽略)。我也为边缘类编写了一个自定义编码器:

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”键?同样,有没有办法获取“Name”? “年龄”等,以便我可以重建 Actor /电影对象,然后使用它们来重建边缘?有没有更好的方法来对我的对象进行编码?我也尝试过关注 this教程,但我发现对象字典的使用对其编码器来说令人困惑,并且我不确定如何将该方法扩展到包含自定义对象的自定义对象。

最佳答案

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

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

class EdgeDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **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

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

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

关于json - 如何为复杂对象编写自定义 JSON 解码器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48991911/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com