Object of type Scoreboard is not JSON serializable - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Object of type Scoreboard is not JSON serializable (/thread-20163.html) |
Object of type Scoreboard is not JSON serializable - lsepolis123 - Jul-30-2019 Object of type Scoreboard is not JSON serializable IS ANY OTHER WAY TO serialize this OBJECT ... ? trying a scoreboard for a game... >>> %Run snake-points-pause-sounds-highscores2.py pygame 1.9.6 Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 424, in <module> drawGameOver(surface, data.username, data.points) File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 115, in drawGameOver board = scoreRecord(username, points) File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 355, in scoreRecord serialize("hightscores.txt", board) File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 285, in serialize json.dump(players, f) File "C:\Users\lwdls\Thonny\lib\json\__init__.py", line 179, in dump for chunk in iterable: File "C:\Users\lwdls\Thonny\lib\json\encoder.py", line 438, in _iterencode o = _default(o) File "C:\Users\lwdls\Thonny\lib\json\encoder.py", line 179, in default raise TypeError(f'Object of type {o.__class__.__name__} ' TypeError: Object of type Scoreboard is not JSON serializable # hghscores - start def deserialize(fileName): exists = os.path.isfile(fileName) if exists: # Store configuration file values f = open(fileName, 'r') board = json.load(f) f.close() else: # Keep presets board = Scoreboard() return board def serialize(fileName, players): f = open(fileName, 'w') json.dump(players, f) f.close() class GameEntry: """Represents one entry of a list of high scores.""" def __init__(self, name, score): """Create an entry with given name and score.""" self._name = name self._score = score def get_name(self): """Return the name of the person for this entry.""" return self._name def get_score(self): """Return the score of this entry.""" return self._score def __str__(self): """Return string representation of the entry.""" return '({0}, {1})'.format(self._name, self._score) # e.g., '(Bob, 98)' class Scoreboard: """Fixed-length sequence of high scores in nondecreasing order.""" def __init__(self, capacity=10): """Initialize scoreboard with given maximum capacity. All entries are initially None. """ self._board = [None] * capacity # reserve space for future scores self._n = 0 # number of actual entries def __getitem__(self, k): """Return entry at index k.""" return self._board[k] def __str__(self): """Return string representation of the high score list.""" return '\n'.join(str(self._board[j]) for j in range(self._n)) def add(self, entry): """Consider adding entry to high scores.""" score = entry.get_score() # Does new entry qualify as a high score? # answer is yes if board not full or score is higher than last entry good = self._n < len(self._board) or score > self._board[-1].get_score() if good: if self._n < len(self._board): # no score drops from list self._n += 1 # so overall number increases # shift lower scores rightward to make room for new entry j = self._n - 1 while j > 0 and self._board[j-1].get_score() < score: self._board[j] = self._board[j-1] # shift entry from j-1 to j j -= 1 # and decrement j self._board[j] = entry # when done, add new entry def scoreRecord(username, points): board = deserialize("hightscores.txt") entry = GameEntry(username, points) board.add(entry) serialize("hightscores.txt", board) return board RE: Object of type Scoreboard is not JSON serializable - fishhook - Jul-30-2019 json.dump takes non mandatory param encoder Use https://docs.python.org/3/library/json.html#json.JSONEncoder to customize encoder RE: Object of type Scoreboard is not JSON serializable - lsepolis123 - Jul-30-2019 In my case... of custom object of type class Scoreboard what can try / use ??? or is better use Writing Your Own Serializer ??? RE: Object of type Scoreboard is not JSON serializable - fishhook - Jul-31-2019 Ok,I've just created my own class SuperClass. Do you know, how to convert it's object into JSON? Of course, nobody knows except me. You have to write your own serializer. I can suggest solution like this: import json class Foo(object): def __init__(self): self.a = 1 self.b = 1 def __json__(self): return dict(a=self.a, b=self.b) class MyUniversalEncoder(json.JSONEncoder): def default(self, obj): if hasattr(obj, "__json__"): return obj.__json__() return json.JSONEncoder.default(self, obj) f = Foo() print json.dumps(f, cls=MyUniversalEncoder) RE: Object of type Scoreboard is not JSON serializable - lsepolis123 - Jul-31-2019 I solve the problem using Scoreboard object and my own serializer/deserializer text file(storage.txt) is like Player1username, 1600 Player3username, 800 Player2username, 500 .... .... this i ask is is any python 3 serializer/deserializer build-in func to store the object Scoreboard in file txt or binary file ... ? RE: Object of type Scoreboard is not JSON serializable - fishhook - Jul-31-2019 Quote:is any python 3 serializer/deserializer build-in func to store the object Scoreboard in file txt What do you think json.dump does? RE: Object of type Scoreboard is not JSON serializable - snippsat - Jul-31-2019 Look at jsonpickle. A quick example and i have removed getter/setter which in not popular or not needed for simple simple attribute access. For more advance attribute access that return a value can use @property .import jsonpickle class GameEntry: """Represents one entry of a list of high scores.""" def __init__(self, name, score): """Create an entry with given name and score.""" self.name = name self.score = score def __str__(self): """Return string representation of the entry.""" return f'({self.name}, {self.score})' # e.g., '(Bob, 98)' obj = GameEntry('Bob', 98) frozen = jsonpickle.encode(obj) # To disk with open('score.json', 'w') as j_out: print(frozen, file=j_out) # From disk with open('score.json') as j: frozen_obj = jsonpickle.decode(j.read())Test frozen_obj: >>> frozen_obj.name 'Bob' >>> frozen_obj.score 98 >>> print(frozen_obj) (Bob, 98) RE: Object of type Scoreboard is not JSON serializable - lsepolis123 - Jul-31-2019 (Jul-31-2019, 10:10 AM)fishhook Wrote:Quote:is any python 3 serializer/deserializer build-in func to store the object Scoreboard in file txt If I want save... use binary or text file ? RE: Object of type Scoreboard is not JSON serializable - fishhook - Aug-01-2019 (Jul-31-2019, 04:41 PM)lsepolis123 Wrote:(Jul-31-2019, 10:10 AM)fishhook Wrote: What do you think json.dump does? It looks like to be impossible to save python object to text. class Foo: pass a = Foo() def log(text): print(text) a.log = log a.log("foo")To save "a" object to a file it is required to save the byte-code of "log" function either. To save the object completely there is "pickle" and "cPickle" packages. Both of them make binary from python object. But assume, that you need to pass a data from web-server to web-client. You can't use pickle for that because JavaScript knows nothing about python's bytecode and it's impossible to convert python class to JS class. For that case, another approach is applied. You have to convert your python object to some format, but the result can only contain data, not methods. So that type of serialization can be text(JSON, YAML, XML) or binary(protobuf, MessagePack). Choose the format you need. RE: Object of type Scoreboard is not JSON serializable - lsepolis123 - Aug-13-2019 def deserialize(fileName): # From disk with open(fileName) as j: frozen_obj = jsonpickle.decode(j.read()) return frozen_obj def serialize(fileName, frozen): # To disk with open(fileName, 'w') as j_out: print(frozen, file=j_out) if __name__ == '__main__': for e in ( ('Rob', 750), ('Mike',1105), ('Rose', 590), ('Jill', 740), ('Jack', 510), ('Anna', 660), ('Paul', 720), ('Bob', 400), ): ge = GameEntry(e[0], e[1]) frozen = jsonpickle.encode(ge) serialize("hightscores.json", frozen) // how to append with jsonpickle... above add only last one... well? Also How get all users back, after append all in json to file? // hightscores.json {"_name": "Bob", "_score": 400, "py/object": "__main__.GameEntry"} |