1

EDIT: updated code, NO LONGER GIVES SPECIFIED ERROR

I am attempting to encode the following into json format:

class Map:
    """
    Storage for cities and routes
    """

    def __init__(self):
        self.cities = {}
        self.routes = {}

class Route: """ Stores route info """

def __init__(self, src, dest, dist):
    self.flight_path = src + '-' + dest
    self.src = src
    self.dest = dest
    self.dist = dist

def to_json(self):
    return {'source': self.src, 'destination': self.dest, 
    'distance': self.dist}

class City: """ Stores city info """

def __init__(self, code, name, country, continent, 
             timezone, coordinates, population, region):
    self.code = code
    self.name = name
    self.country = country
    self.continent = continent
    self.timezone = timezone
    self.coordinates = coordinates
    self.population = population
    self.region = region

def to_json(self):
    return {'code': self.code, 'name': self.name, 'country': self.country, 
    'continent': self.continent, 'timezone':  self.timezone, 
    'coordinates': self.coordinates, 'population': self.population, 
    'region': self.region}

I would like a "cities" section of python encoding all the city information stored in map.cities and a "routes" section encoding all the route information stored in map.routes

My attempt:

def map_to_json(my_file, air_map):
    """
    Saves JSON Data
    """
    with open(my_file, 'w') as outfile:
        for entry in air_map.cities:
            json.dumps(air_map.cities[entry].to_json(), outfile)
        for entry in air_map.routes:
            json.dumps(air_map.routes[entry].to_json(), outfile)

    outfile.close()

where air_map is a map and my_file is a file path.

I get the following error:

>    Jmap.map_to_json('Resources/map_save.json', air_map)   File
> "JSONToMap.py", line 53, in map_to_json
>     json.dumps(air_map.cities, outfile)   File "C:\Python27\lib\json\__init__.py", line 250, in dumps
>     sort_keys=sort_keys, **kw).encode(obj)   File "C:\Python27\lib\json\encoder.py", line 207, in encode
>     chunks = self.iterencode(o, _one_shot=True)   File "C:\Python27\lib\json\encoder.py", line 270, in iterencode
>     return _iterencode(o, 0)   File "C:\Python27\lib\json\encoder.py", line 184, in default
>     raise TypeError(repr(o) + " is not JSON serializable") TypeError: <City.City instance at 0x0417FC88> is not JSON serializable
> >>>

I am very new to python, and to JSON, so help would be appreciated.

Thanks

Kyle Grage
  • 715
  • 1
  • 9
  • 15
  • 1
    Simply your class is not JSON serializable. Check that link: http://stackoverflow.com/questions/3768895/python-how-to-make-a-class-json-serializable – Rami Oct 04 '13 at 02:34

1 Answers1

2

You cannot serialize objects directly. Try this instead:

class City:
    """
    Stores city info
    """

    def __init__(self, code, name, country, continent, 
                 timezone, coordinates, population, region):
        self.code = code
        self.name = name
        self.country = country
        self.continent = continent
        self.timezone = timezone
        self.coordinates = coordinates
        self.population = population
        self.region = region

    def to_json(self):
        return {'code': self.code, 'name': self.name,
                'country': self.country, 
                #rest of the attributes...
               }

and while calling,

json.dumps(air_map.cities.to_json(), outfile)

And similarly for Routes model too.

And if you are dealing with a list of objects, you can always do:

json.dumps([city.to_json() for city in air_map.cities], outfile)

if air_map.cities is a list of cities

karthikr
  • 97,368
  • 26
  • 197
  • 188
  • He could probably get away with just `def to_json(self): return self.__dict__`. – Tim Peters Oct 04 '13 at 02:17
  • @TimPeters Thanks for pointing that out. If __all__ the fields are required in the serialized object, this is definitely a good way to achieve it. – karthikr Oct 04 '13 at 02:20
  • I updated my code to: with open(my_file, 'w') as outfile: for entry in air_map.cities: json.dumps(air_map.cities[entry].to_json(), outfile) for entry in air_map.routes: json.dumps(air_map.routes[entry].to_json(), outfile) outfile.close() **** Does outfile.close() work? **** – Kyle Grage Oct 04 '13 at 02:37
  • This looks wrong, based on the output you have shown (error messag), you should be trying the first example I showed you `json.dumps(air_map.cities.to_json(), outfile)` – karthikr Oct 04 '13 at 03:52