Reputation: 275
I am trying to serialize the dictionary playersElo
for saving/loading it as/from JSON.
But as it's not a serializable object and I can't find a way to do it.
playersElo={} # dictionary of {<int> : <PlayerElo>}
playersElo[1] = PlayerElo()
playersElo[2] = PlayerElo()
...
class PlayerElo:
"""
A class to represent a player in the Elo Rating System
"""
def __init__(self, name: str, id: str, rating):
self.id = id
self.name = name
# comment the 2 lines below in order to start with a rating associated
# to current player rank
self.eloratings = {0: 1500}
self.elomatches = {0: 0}
self.initialrating = rating
Upvotes: 0
Views: 1440
Reputation: 54698
Maybe this can be a starting spot for you. The serializer grabs the __dict__
attribute from the object and makes a new dict-of-dicts, then writes it to JSON. The deserializer creates a dummy object, then updates the __dict__
on the way in.
import json
class PlayerElo:
"""
A class to represent a player in the Elo Rating System
"""
def __init__(self, name: str, id: str, rating):
self.id = id
self.name = name
self.eloratings = {0: 1500}
self.elomatches = {0: 0}
self.initialrating = rating
playersElo={} # dictionary of {<int> : <PlayerElo>}
playersElo[1] = PlayerElo('Joe','123',999)
playersElo[2] = PlayerElo('Bill','456',1999)
def serialize(ratings):
newdict = {i:j.__dict__ for i,j in ratings.items()}
json.dump( newdict, open('x.json','w') )
def deserialize():
o = json.load(open('x.json'))
pe = {}
for k,v in o.items():
obj = PlayerElo('0','0',0)
obj.__dict__.update( v )
pe[int(k)] = obj
return pe
print(playersElo)
serialize( playersElo )
pe = deserialize( )
print(pe)
Upvotes: 2
Reputation: 123443
You can extend the json.JSONEncoder
to handle instances of your class. There are examples in the module's documentation, but here one why of doing it with your PlayerElo
class.
Note: Also see my answer to the question Making object JSON serializable with regular encoder for a more generic way of doing it.
import json
class PlayerElo:
""" A class to represent a player in the Elo Rating System. """
def __init__(self, name: str, id: str, rating):
self.id = id
self.name = name
# comment the 2 lines below in order to start with a rating associated
# to current player rank
self.eloratings = {0: 1500}
self.elomatches = {0: 0}
self.initialrating = rating
class MyJSONEcoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, PlayerElo):
return dict(type='PlayerElo', name=obj.name, id = obj.id,
rating=obj.initialrating)
return super().default(obj)
playersElo={} # dictionary of {<int> : <PlayerElo>}
playersElo[1] = PlayerElo('Bob', 'thx1138', 4)
playersElo[2] = PlayerElo('Sue', 'p-138', 3)
from pprint import pprint
my_encoder = MyJSONEcoder()
pprint(my_encoder.encode(playersElo))
Here the JSON string it generated and printed:
('{"1": {"type": "PlayerElo", "name": "Bob", "id": "thx1138", "rating": 4}, '
'"2": {"type": "PlayerElo", "name": "Sue", "id": "p-138", "rating": 3}}')
Upvotes: 1