Reputation: 5
Trying to import dictionaries from an external Json file using json.loads, however when I do this I am met with an error message.
import json
import random
winner = "None"
winners = 0
class player:
def __init__(self, playernum):
self.playernum = playernum
self.score = random.randint(1,6)
self.name = "foo"
player1 = player(1)
player2 = player(2)
if player1.score > player2.score:
winner = player1.name
winners = player1.score
elif player2.score > player1.score:
winner = player2.name
winners = player2.score
with open("highscores.txt", "a") as f:
json.dump({winner : winners}, f)
f.close()
with open("highscores.txt", "r") as f:
scores = json.load(f)
f.close()
print(scores)
Highscores.txt currently contains 7 dictionaries; {"Daniel": 71}{"Jonathan": 26}{"Jonathan": 58}{"Daniel": 90}{"Jonathan": 57}{"Jonathan": 80}{"Jonathan": 50}
Shouldn't it print out the file, which should be comprised of winner:winners dictionaries? Instead, I get this error message:
Traceback (most recent call last):
File "C:/Users/jonat/AppData/Local/Programs/Python/Python36-32/neacode.py", line 119, in <module>
scores = json.load(f)
File "C:\Users\jonat\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 299, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "C:\Users\jonat\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\jonat\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 342, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 15 (char 14)
Why?
Upvotes: 0
Views: 56
Reputation: 13106
It's because you are appending dictionaries to a file, which is not valid json syntax:
from io import StringIO
import json
s = '''{"a": 1}
{"b": 2}
{"c": 3}'''
fh = StringIO(s)
json.load(fh) # JSONDecodeError
Furthermore, using json.dump
in a file opened in append ('a'
) mode won't include newlines, which yields even worse non-json. To handle this, I'd change how you append to the file:
with open('highscores.txt', 'a') as fh:
obj = json.dumps({winner: winners})+'\n' # note the added newline here
fh.write(obj)
This will allow you to read in the file line by line:
with open('highscores.txt', 'r') as fh:
scores = [json.loads(line.strip()) for line in fh]
print(scores)
Also, note that you don't have to call fh.close()
as the with
statement will take care of that for you
Upvotes: 1