Python JSONDecodeError is always called

Question:

I am trying to save a score and coin amount from a game in python. The format looks like this:

{"score": score, "coins": coins}

where the variables score and coins represent a different number. I save this data by doing this:

with open(os.path.join(save_dir, 's.bin'), 'w') as save_file:
    json.dump(data, save_file)

And the output is correct, as it is this (for example):

{"score": 34.060000000000166, "coins": 0}

in the file. But when the game is closed and reopened, the score is loaded in with this:

try:
    with open(os.path.join(save_dir, 's.bin')) as save_file:
        try:
            print("attempting to load file...")
            json.load(save_file)
            return json.load(save_file)
        except JSONDecodeError:
            print("JSON can't decode...")
            with open(os.path.join(save_dir, 's.bin'), 'w') as save_file_2:
                json.dump(data_layout, save_file_2)
                return data_layout
except FileNotFoundError:
    print("file not found...")
    with open(os.path.join(save_dir, 's.bin'), 'w') as save_file_3:
        json.dump(data_layout, save_file_3)
        return data_layout

Where data_layout is: {“score”: 0, “coins”: 0}.But the JSONDecodeError is always called on startup, so it always resets the score and coins on startup. It saves correctly, but it doesn’t load correctly. All help is appreciated!

Asked By: RJ Carter

||

Answers:

There are two issues in the posted code.

  1. In the first part, you’re trying to read the JSON file twice. The second time, the file pointer is at the end of the file and JSON loader fails to get valid JSON. Remove the line json.load(save_file) and it will correctly read/decode the JSON file.

  2. If json.load() raises JSONDecodeError then the exception handling will be inside the with code block so the file will be open while it attempts to open it again for writing. It’s good practice to close the file first before opening it for writing.

Try something like this:

file = os.path.join(save_dir, 's.bin')
try:
    with open(file) as save_file:
        print("attempting to load file...")
        # json.load(save_file) # <-- remove this line
        return json.load(save_file)
except JSONDecodeError:
    print("JSON can't decode...")
    with open(file, 'w') as save_file_2:
        json.dump(data_layout, save_file_2)
    return data_layout
except FileNotFoundError:
    print("file not found...")
    with open(file, 'w') as save_file_3:
        json.dump(data_layout, save_file_3)
    return data_layout
Answered By: CodeMonkey
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.