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.

json functionPython 2.6+Live demo
Common call
with open(path, encoding='utf-8') as f: data = json.load(f)
Returns
dict, list, str, int, float, bool or None
Replaces
json.loads(f.read())
Watch out
it takes a file object, not a file name
json.load(fpfp — 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.type: file object · required, *, clscls — Custom decoder class; the other keyword arguments are passed to it.type: JSONDecoder subclass · default: None=None, object_hookobject_hook — Called with every decoded dict; its return value replaces the dict.type: callable · default: None=None, parse_floatparse_float — Called with the text of every JSON float — decimal.Decimal for exact values.type: callable · default: None=None, parse_intparse_int — Called with the text of every JSON int.type: callable · default: None=None, parse_constantparse_constant — Called with '-Infinity', 'Infinity' or 'NaN'.type: callable · default: None=None, object_pairs_hookobject_pairs_hook — Called with the list of (key, value) pairs of every object, duplicates included.type: callable · default: None=None, **kw)
→ dict | list | str | int | float | bool | None

Demo

Live evaluation
io.StringIO turns a str into an in-memory file — json.load reads it exactly like a file on disk.
Try:
Inputs
textstrthe file content
Code
import io, json
json.load(io.StringIO('{"debug": true, "port": 8080}'))
Result
{'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

NameTypeRequiredDescription
fpfile objectyesAnything 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_hookcallableno (None)Called with every decoded dict; its return value replaces the dict.
object_pairs_hookcallableno (None)Called with the list of (key, value) pairs of every object, duplicates included.
parse_floatcallableno (None)Called with the text of every JSON float — decimal.Decimal for exact values.
parse_intcallableno (None)Called with the text of every JSON int.
parse_constantcallableno (None)Called with '-Infinity', 'Infinity' or 'NaN'.
clsJSONDecoder subclassno (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

Read a JSON file
Always name the encoding — the default depends on the platform.
import json
with open('config.json', encoding='utf-8') as f:
    config = json.load(f)
Accept files with or without a BOM
'utf-8-sig' reads plain UTF-8 too, and drops a leading byte-order mark if there is one.
import json
with open(path, encoding='utf-8-sig') as f:
    data = json.load(f)
Read JSON Lines
One document per line: parse the lines, skip blank ones.
import json
with open('events.jsonl', encoding='utf-8') as f:
    events = [json.loads(line) for line in f if line.strip()]
Report where the file is broken
JSONDecodeError carries line and column.
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

1. Read a file
import json with open('config.json', 'w', encoding='utf-8') as f: f.write('{"debug": true, "port": 8080}') with open('config.json', encoding='utf-8') as f: config = json.load(f) config
Returns
{'debug': True, 'port': 8080}
2. Any object with read()
import io, json json.load(io.StringIO('[1, 2]'))
Returns
[1, 2]
3. Binary mode handles the BOM
import json with open('bom.json', 'wb') as f: f.write(b'\xef\xbb\xbf{"a": 1}') with open('bom.json', 'rb') as f: data = json.load(f) data
Returns
{'a': 1}
4. Binary mode detects UTF-16
import json with open('u16.json', 'w', encoding='utf-16') as f: f.write('{"name": "Zoë"}') with open('u16.json', 'rb') as f: data = json.load(f) data
Returns
{'name': 'Zoë'}
5. It reads to the end
import io, json f = io.StringIO('[1] ') (json.load(f), f.read())
Returns
([1], '')
6. Exact decimals
import io, json from decimal import Decimal json.load(io.StringIO('{"price": 19.99}'), parse_float=Decimal)
Returns
{'price': Decimal('19.99')}
7. An empty file
import json open('empty.json', 'w').close() with open('empty.json', encoding='utf-8') as f: data = json.load(f)
Returns
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Pitfalls

1. Passing the file name
load calls .read() on its argument, and a str has no read(). Open the file first (json.loads would try to parse the name itself).
load(path)
import json
json.load('config.json')
AttributeError: 'str' object has no attribute 'read'
load(open file)
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
{'ok': True}
2. A byte-order mark at the start
Files saved as "UTF-8 with BOM" start with U+FEFF. Read as 'utf-8', the mark is part of the text and load rejects it; 'utf-8-sig' removes it.
encoding='utf-8'
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)
json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)
encoding='utf-8-sig'
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
{'a': 1}
3. JSON Lines is not one JSON document
A .jsonl / NDJSON file has one document per line. load parses the first and fails on the rest.
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.load(f)
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 10)
line by line
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
[{'id': 1}, {'id': 2}]
4. Loading the same file object twice
The first load read to the end; the second gets an empty string. Rewind with seek(0), or keep the result.
load, load
import io, json
f = io.StringIO('{"a": 1}')
data = json.load(f)
again = json.load(f)
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
seek(0)
import io, json
f = io.StringIO('{"a": 1}')
data = json.load(f)
f.seek(0)
again = json.load(f)
again
{'a': 1}

When to use

Use it
  • Reading a .json file (config, fixtures, exported data)
  • Parsing a response or stream object that has read()
Reach for something else
  • 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

CPython impl
Lib/json/__init__.py: load(fp, **kw) is loads(fp.read(), **kw) — every error and option is the same as json.loads
Binary files
fp.read() returning bytes is fine: loads detects UTF-8, UTF-16 or UTF-32 from the first bytes and accepts a UTF-8 BOM
Text files
In text mode the file's encoding decodes the bytes before json sees them — a UTF-8 BOM survives 'utf-8' decoding and is rejected

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()).