json.load
Hand it an open file, get back dicts and lists. It reads the whole file as ONE document — a second document, an empty file or a byte-order mark decoded as plain UTF-8 text all end in JSONDecodeError.
Demo
import io, json json.load(io.StringIO('{"debug": true, "port": 8080}'))
json.load checks for the BOM itself: reading the utf-8-sig file with plain 'utf-8' leaves U+FEFF at the start of the text, and load refuses it with 'Unexpected UTF-8 BOM (decode using utf-8-sig)'. 'utf-8-sig' strips it. In JSON Lines, load parses the first line, then finds more text: 'Extra data' at line 2, column 1. A bad line is not caught by the try, so its error surfaces from the list comprehension.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| fp | file object | yes | Anything with a read() method returning the whole document: a file opened in text mode, a binary file (UTF-8/16/32 detected, BOM accepted), io.StringIO, io.BytesIO. |
| object_hook | callable | no (None) | Called with every decoded dict; its return value replaces the dict. |
| object_pairs_hook | callable | no (None) | Called with the list of (key, value) pairs of every object, duplicates included. |
| parse_float | callable | no (None) | Called with the text of every JSON float — decimal.Decimal for exact values. |
| parse_int | callable | no (None) | Called with the text of every JSON int. |
| parse_constant | callable | no (None) | Called with '-Infinity', 'Infinity' or 'NaN'. |
| cls | JSONDecoder subclass | no (None) | Custom decoder class; the other keyword arguments are passed to it. |
Return value
dict | list | str | int | float | bool | None — The Python value of the JSON document in the file.
Common patterns
import json with open('config.json', encoding='utf-8') as f: config = json.load(f)
import json with open(path, encoding='utf-8-sig') as f: data = json.load(f)
import json with open('events.jsonl', encoding='utf-8') as f: events = [json.loads(line) for line in f if line.strip()]
import json try: with open(path, encoding='utf-8') as f: data = json.load(f) except json.JSONDecodeError as e: raise SystemExit(f'{path}:{e.lineno}:{e.colno}: {e.msg}')
Examples
Pitfalls
import json json.load('config.json')
import json from pathlib import Path Path('config.json').write_text('{"ok": true}', encoding='utf-8') with open('config.json', encoding='utf-8') as f: data = json.load(f) data
import json from pathlib import Path Path('data.json').write_text('{"a": 1}', encoding='utf-8-sig') with open('data.json', encoding='utf-8') as f: data = json.load(f)
import json from pathlib import Path Path('data.json').write_text('{"a": 1}', encoding='utf-8-sig') with open('data.json', encoding='utf-8-sig') as f: data = json.load(f) data
import json from pathlib import Path Path('log.jsonl').write_text('{"id": 1}\n{"id": 2}\n', encoding='utf-8') with open('log.jsonl', encoding='utf-8') as f: data = json.load(f)
import json from pathlib import Path Path('log.jsonl').write_text('{"id": 1}\n{"id": 2}\n', encoding='utf-8') with open('log.jsonl', encoding='utf-8') as f: data = [json.loads(line) for line in f] data
import io, json f = io.StringIO('{"a": 1}') data = json.load(f) again = json.load(f)
import io, json f = io.StringIO('{"a": 1}') data = json.load(f) f.seek(0) again = json.load(f) again
When to use
- Reading a .json file (config, fixtures, exported data)
- Parsing a response or stream object that has read()
- You already have the text → json.loads
- JSON Lines / NDJSON files → json.loads per line
- Huge files you want to stream → a streaming parser (load always reads everything into memory)
Notes
FAQ
load takes a file object and reads it; loads takes the JSON text itself (str or bytes). json.load(f) is exactly json.loads(f.read()).