Free tools Windows power users keep installed
One-click scans. No signup required.
Use Python’s built-in json module and an open() context manager:
import json
with open("data.json", encoding="utf-8") as file:
data = json.load(file)
open() locates and reads the file, while json.load() parses one complete JSON document into Python data. No third-party package is required.
The simplest way to load a JSON file
import json
with open("data.json", "r", encoding="utf-8") as file:
data = json.load(file)
print(data)
The "r" mode is optional because reading is open()’s default. Specifying encoding="utf-8" makes the intended text encoding explicit. The with statement closes the file automatically, even when an error occurs. Python’s open() function returns a file object, and json.load() reads that object’s contents and deserializes them.
A complete example
Create data.json
{
"name": "Ada",
"age": 36,
"languages": ["Python", "C"]
}
Read and use it
import json
with open("data.json", encoding="utf-8") as file:
person = json.load(file)
print(person["name"])
print(person["age"])
print(person["languages"])
Output:
Ada
36
['Python', 'C']
A JSON object becomes a Python dict, so use string keys. A JSON array becomes a Python list, so use indexes or iterate over it:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →#1 Best Overall
[
{"name": "Ada", "active": true},
{"name": "Grace", "active": false}
]
with open("users.json", encoding="utf-8") as file:
users = json.load(file)
for user in users:
print(user["name"], user["active"])
json.load() versus json.loads()
| Function | Input | Typical use |
|---|---|---|
json.load(file_object) |
An open file-like object with .read() |
Parse JSON directly from a file |
json.loads(value) |
A JSON string, bytes, or bytearray | Parse text already held in memory |
import json
text = '{"name": "Ada"}'
data = json.loads(text)
This is not valid:
json.load("data.json")
A filename string is not a file object. Open the file first, or use Path.open(). In modern Python, json.loads() does not take an encoding keyword; choose the encoding when reading the file.
Load JSON with pathlib
import json
from pathlib import Path
path = Path("data.json")
with path.open("r", encoding="utf-8") as file:
data = json.load(file)
Path.open() accepts the same important mode and encoding arguments as open(). For a small file, this shorter alternative reads all text first:
import json
from pathlib import Path
data = json.loads(Path("data.json").read_text(encoding="utf-8"))
Parsing from the open file avoids a separate full-text string and makes the file-versus-parser distinction clearer; read_text() is convenient for small configuration files.
What JSON values become in Python
| JSON | Python |
|---|---|
| object | dict |
| array | list |
| string | str |
| number | int or float |
true/false |
True/False |
null |
None |
The top-level value can also be a string, number, boolean, or null; it does not have to be an object or array.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Fix common loading errors
FileNotFoundError
from pathlib import Path
import json
path = Path("data.json")
try:
with path.open(encoding="utf-8") as file:
data = json.load(file)
except FileNotFoundError:
print(f"File not found: {path}")
A relative path is resolved from the process’s current working directory, not necessarily the directory containing your script. Check it with:
from pathlib import Path
print(Path.cwd())
To locate a file beside a regular script:
from pathlib import Path
import json
json_path = Path(__file__).resolve().parent / "data.json"
with json_path.open(encoding="utf-8") as file:
data = json.load(file)
__file__ is normally available in a script, but not in every notebook or interactive environment.
Invalid JSON: JSONDecodeError
import json
try:
with open("data.json", encoding="utf-8") as file:
data = json.load(file)
except json.JSONDecodeError as error:
print(f"Message: {error.msg}")
print(f"Line: {error.lineno}, column: {error.colno}")
print(f"Character position: {error.pos}")
JSONDecodeError is a ValueError subclass. Typical causes include:
- Single quotes instead of JSON’s required double quotes:
{"name": "Ada"} - Trailing commas, comments, or unquoted property names
- Python literals such as
True,False, orNoneinstead oftrue,false, ornull - An empty or truncated file
- Two documents concatenated where one document is expected
Encoding errors and UTF-8 BOMs
JSON permits UTF-8, UTF-16, and UTF-32; UTF-8 is recommended for interoperability (RFC 8259). Use the encoding that produced the file:
Rank #3
with open("data.json", encoding="utf-16") as file:
data = json.load(file)
If software added a UTF-8 byte-order mark (BOM), Python can reject it. Try utf-8-sig as a recovery option, or regenerate the file without a BOM:
with open("data.json", encoding="utf-8-sig") as file:
data = json.load(file)
Valid syntax, wrong shape
Parsing does not enforce your application’s schema. Check the structure and types after loading:
if not isinstance(data, dict):
raise TypeError("Expected a top-level JSON object")
if not isinstance(data.get("age"), int):
raise TypeError("Expected age to be an integer")
Validate from the command line
python -m json.tool data.json
This standard-library command parses and pretty-prints valid JSON, or reports a location for a syntax error. To request two-space indentation:
python -m json.tool --indent 2 data.json
The --json-lines option parses one JSON value per line and was added in Python 3.8; command-line options vary across older Python releases. See the json.tool documentation.
Rank #4
JSON Lines requires different code
Ordinary JSON contains one complete document, such as an array:
[
{"id": 1},
{"id": 2}
]
JSON Lines (NDJSON) contains one document on each line:
{"id": 1}
{"id": 2}
Calling json.load() on the second format generally raises an “extra data” error. For a small file:
import json
with open("events.jsonl", encoding="utf-8") as file:
events = [json.loads(line) for line in file if line.strip()]
For larger files, process each line without collecting everything:
import json
with open("events.jsonl", encoding="utf-8") as file:
for line_number, line in enumerate(file, start=1):
if not line.strip():
continue
try:
event = json.loads(line)
except json.JSONDecodeError as error:
print(f"Invalid JSON on line {line_number}: {error}")
continue
process(event)
Large or untrusted files
json.load() parses one complete document and normally builds its Python representation in memory. The standard library does not provide general streaming for arbitrarily large nested JSON. Set input-size limits for attacker-controlled data: malicious JSON can consume substantial CPU or memory. Valid syntax also says nothing about acceptable keys, types, values, or business rules; add schema or application validation. Never use eval() to parse JSON.
For very large datasets, consider JSON Lines with incremental processing, a streaming parser, a database, or a columnar format. The Python implementation notes explain why application-level limits matter.
Useful advanced options
Preserve decimal precision
import json
from decimal import Decimal
with open("prices.json", encoding="utf-8") as file:
prices = json.load(file, parse_float=Decimal)
Without this option, JSON decimals become Python float values.
Build custom objects
def as_user(obj):
if "name" in obj and "email" in obj:
return User(name=obj["name"], email=obj["email"])
return obj
with open("users.json", encoding="utf-8") as file:
users = json.load(file, object_hook=as_user)
object_hook is optional; ordinary JSON objects become dictionaries.
Reject non-standard numbers
import json
def reject_nonstandard_number(value):
raise ValueError(f"Non-standard JSON number: {value}")
with open("data.json", encoding="utf-8") as file:
data = json.load(file, parse_constant=reject_nonstandard_number)
Python accepts NaN, Infinity, and -Infinity by default, although they are outside standard JSON number syntax.
A reusable loader with clear errors
import json
from pathlib import Path
def load_json(path: str | Path):
path = Path(path)
try:
with path.open(encoding="utf-8") as file:
return json.load(file)
except FileNotFoundError:
raise RuntimeError(f"JSON file does not exist: {path}") from None
except json.JSONDecodeError as error:
raise RuntimeError(
f"Invalid JSON in {path} at line {error.lineno}, "
f"column {error.colno}: {error.msg}"
) from error
Choose separately whether a missing optional file should return a fallback, whether invalid configuration should stop startup, and where the original exception should be logged. Avoid a bare except:, which can hide unrelated programming errors.
Quick Recap
Quick reference
import json
with open("data.json", encoding="utf-8") as file:
data = json.load(file)
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

