タイトルが言うように、クラスを定義した他のオブジェクトを含む、クラスを定義したオブジェクトのカスタムデコーダーを記述しようとしています。 「外部」クラスは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
"inner"クラスの俳優と映画は次のように定義されています。
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
(スープは、その映画/俳優のWikipediaページの美しいスープオブジェクトです。無視してかまいません)。 Edgeクラスのカスタマーエンコーダーも作成しました。
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ファイルに適切にシリアル化します。ここで、Edgeデコーダーを作成しようとすると問題が発生します。私はgithubページ here を参照として使用しましたが、私のエンコーダは彼から逸脱しており、変更する必要があるかどうか疑問に思っています。オブジェクトのタイプを、JSONシリアライゼーション内の独自のキーと値のペアとして明示的にエンコードする必要がありますか?それとも、エッジのシリアライゼーションで「Actor」キーと「Movie」キーを取得する方法はありますか?同様に、「名前」を取得する方法はありますか。 「年齢」などで、Actor/Movieオブジェクトを再構築し、それらを使用してエッジを再構築できるようにしますか?代わりにオブジェクトをエンコードするより良い方法はありますか?私は this のチュートリアルも試しましたが、オブジェクトディクテーションの使用がエンコーダーを混乱させることに気づき、そのメソッドをカスタムオブジェクトを含むカスタムオブジェクトに拡張する方法がわかりませんでした。
参照するエンコーダー/デコーダーの例( ここ )は、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
質問のコードを使用してクラス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