title: How to write a custom JSON decoder for a complex object?
body: <p>Like the title says, I'm trying to write a custom decoder for an object whose class I've defined which contains other objects whose class I've defined. The &quot;outer&quot; class is an Edge, defined like so:</p>
  <pre><code>class Edge:
      def __init__(self, actor, movie):
          self.actor = actor
          self.movie = movie
  
      def __eq__(self, other):
          if (self.movie == other.movie) &amp; (self.actor == other.actor):
              return True
          else:
              return False
  
      def __str__(self):
          print(&quot;Actor: &quot;, self.actor, &quot; Movie: &quot;, self.movie)
  
      def get_actor(self):
          return self.actor
  
      def get_movie(self):
          return self.movie
  </code></pre>
  <p>with the &quot;inner&quot; classes actor and movies are defined like so:</p>
  <pre><code>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
  </code></pre>
  <p>(soup is just a beautifulsoup object for that movie/actor's Wikipedia page, it can be ignored).
  I've written a custom encoder for the edge class as well:</p>
  <pre><code>class EdgeEncoder(json.JSONEncoder):
      def default(self, o):
          if isinstance(o, Edge):
              return {
                      &quot;Actor&quot;: {
                               &quot;Name&quot;: o.get_actor().get_name(),
                               &quot;Age&quot;: o.get_actor().get_age()
                               },
                      &quot;Movie&quot;: {
                               &quot;Title&quot;: o.get_movie().get_title(),
                               &quot;Gross&quot;: o.get_movie().get_gross(),
                               &quot;Year&quot;: o.get_movie().get_year()
                               }
                      }
          return json.JSONEncoder.default(self, o)
  </code></pre>
  <p>which I've tested, and it properly serializes a list of edges into a JSON file. Now my problem comes when trying to write an edge decoder. I've used the GitHub page <a href="https://gist.github.com/simonw/7000493" rel="noreferrer">here</a> as a reference, but my encoder deviates from him and I'm wondering if it's necessary to change it. Do I need to explicitly encode an object's type as its own key-value pair within its JSON serialization the way he does, or is there some way to grab the &quot;Actor&quot; and &quot;Movie&quot; keys with the serialization of the edge? Similarly, is there a way to grab &quot;Name&quot;? &quot;Age&quot;, etc, so that I can reconstruct the Actor/Movie object, and then use those to reconstruct the edge? Is there a better way to go about encoding my objects instead? I've also tried following <a href="https://code.tutsplus.com/tutorials/serialization-and-deserialization-of-python-objects-part-1--cms-26183" rel="noreferrer">this</a> tutorial, but I found the use of object dicts confusing for their encoder, and I wasn't sure how to extend that method to a custom object which contains custom objects.</p>