Read a JSON file
Read a JSON file with json.load(f). A file saved with a byte order mark fails until opened as utf-8-sig, and a repeated key keeps only the last value.
A JSON file that looks fine in an editor fails to parse with an error about a byte order mark.
import json
with open("bom.json", "wb") as f:
f.write(b'\xef\xbb\xbf{"a": 1}')
try:
with open("bom.json", encoding="utf-8") as f:
json.load(f)
except json.JSONDecodeError as e:
print("error:", e)
with open("bom.json", encoding="utf-8-sig") as f:
print(json.load(f))
with open("odd.json", "w") as f:
f.write('{"a": 1, "a": 2, "n": NaN, "big": 12345678901234567890123}')
with open("odd.json") as f:
print(json.load(f))error: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)
{'a': 1}
{'a': 2, 'n': nan, 'big': 12345678901234567890123}json.load reads a file object and json.loads a string. A file saved with a leading byte order mark, as some Windows tools do, is rejected by the utf-8 codec with a message that names the fix, and the utf-8-sig codec drops the mark. The second file shows behavior that surprises people: a repeated key silently keeps the last value, NaN is accepted although it is not JSON, and integers have no size limit. These are documented in the json module.
To reject the extensions, pass parse_constant to raise on NaN, and object_pairs_hook to catch duplicate keys. Use json.load on a file opened in text mode, or hand it bytes through json.loads, which detects the encoding. For very large files, a streaming parser such as ijson avoids loading everything at once.