Skip to content

What Are the Differences Between json.load() and json.loads() in Python

Learn how to correctly use json.load() for file objects and json.loads() for strings in Python to parse JSON data without errors.

Python's json module provides two functions for converting JSON data into Python objects: json.load() and json.loads(). The distinction is straightforward: the "s" in loads stands for "string." One reads JSON from a file, the other parses JSON from a string already in memory. Mixing them up is one of the most common mistakes when working with JSON in Python.

This guide explains when to use each function, shows the errors you get when you confuse them, and covers practical patterns for handling JSON from different sources.

json.loads(): Parse JSON from a String

json.loads() takes a JSON-formatted string and converts it into a Python object. This is the function you use when working with API responses, data received over a network, or any JSON that is already stored in a variable:

import json

api_response = '{"id": 1, "status": "ok", "data": [1, 2, 3]}'

data = json.loads(api_response)

print(data["status"])
print(data["data"])
print(type(data))

Output:

ok
[1, 2, 3]
<class 'dict'>

The JSON string is parsed into a native Python dictionary that you can work with directly.

json.load(): Read and Parse JSON from a File

json.load() reads JSON directly from a file object opened with open(). It handles both reading the file content and parsing the JSON in a single step:

import json

with open("config.json", "r") as f:
    config = json.load(f)

print(config)
print(type(config))

If config.json contains {"database": {"host": "localhost", "port": 5432}}, the output is:

{'database': {'host': 'localhost', 'port': 5432}}
<class 'dict'>

Common Mistake: Mixing Up the Two Functions

Passing the wrong type of argument to each function produces clear but different errors. Recognizing these error messages helps you quickly identify the problem:

import json

with open("data.json") as f:
    try:
        data = json.loads(f)
    except TypeError as e:
        print(f"Error: {e}")

Output:

Error: the JSON object must be str, bytes or bytearray, not TextIOWrapper
import json

json_str = '{"key": "value"}'
try:
    data = json.load(json_str)
except AttributeError as e:
    print(f"Error: {e}")

Output:

Error: 'str' object has no attribute 'read'

The fix in both cases is to use the correct function:

import json

with open("data.json") as f:
    data = json.load(f)

json_str = '{"key": "value"}'
data = json.loads(json_str)

Reading a File as a String, Then Parsing

Sometimes you need to read the file content first for inspection, validation, or logging before parsing it. In that case, you read the file into a string with .read() and then use json.loads():

import json

with open("data.json", "r") as f:
    content = f.read()      # content is now a string

print(f"Raw JSON ({len(content)} characters):")
print(content[:100])

data = json.loads(content)  # parse the string
print(f"\nParsed type: {type(data)}")

This is functionally equivalent to using json.load(f) directly, but gives you access to the raw JSON string before parsing.

Handling Character Encoding

JSON files sometimes contain non-ASCII characters. Specifying the encoding when opening the file prevents decoding errors:

import json

with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)

json_bytes = b'{"name": "Alice"}'

data = json.loads(json_bytes.decode("utf-8"))

data = json.loads(json_bytes)

print(data)

Output:

{'name': 'Alice'}

Parsing JSON Lines Format

Some data files use the JSON Lines format (.jsonl), where each line is a separate, independent JSON object. Since the file as a whole is not valid JSON, you cannot use json.load() on the entire file. Instead, read each line and parse it individually with json.loads():

import json


with open("events.jsonl", "r") as f:
    events = [json.loads(line) for line in f if line.strip()]

for event in events:
    print(f"{event['user']}: {event['event']}")

Output:

alice: login
bob: purchase
alice: logout

Common Errors and How to Fix Them

Error Message Cause Fix
TypeError: must be str, not TextIOWrapper Passed a file object to loads() Use load() instead
AttributeError: 'str' has no attribute 'read' Passed a string to load() Use loads() instead
JSONDecodeError: Expecting property name Single quotes in JSON string Replace with double quotes
JSONDecodeError: Extra data Multiple JSON objects in one string Parse line by line with loads()

The Complete json Module Pattern

The "s" suffix convention applies consistently across all four primary functions in the json module:

Function Source/Target Direction Typical Use Case
json.load() File object JSON to Python Reading configuration files, loading saved data
json.loads() String JSON to Python Parsing API responses, processing received data
json.dump() File object Python to JSON Saving configuration, exporting data
json.dumps() String Python to JSON Building API responses, logging

Summary

  • Use json.load() when reading JSON from a file object opened with open().
  • Use json.loads() when parsing a JSON string from an API response, a database field, or any variable already in memory.

The "s" suffix consistently means "string" across the entire json module, applying equally to dump()/dumps() for serialization.

Mixing up the two functions produces clear error messages (TypeError for loads() with a file, AttributeError for load() with a string), so if you see either of these errors, check which function you are using and switch to the correct one.

Navigation