Skip to content
Theory · Modules, files and generators · lesson 5 of 12

The JSON format

Picture a move. A whole wardrobe will not fit into a parcel. It is taken apart into flat boards, the assembly instructions go into the box, and at the new place it is put together again. You get the same wardrobe, although it is a new assembly.

The same thing happens to a program's data. The write method puts only strings into a file, while a program's data are dicts, lists and numbers. They have to be turned into a string and later built back. This conversion is called serialization.

The most common text format for it is JSON. It is like a standard box that any delivery service accepts: programs in any language read JSON. In Python, the json module works with it:

Python
import json

data = {"name": "Ann", "langs": ["python", "go"], "admin": False}
text = json.dumps(data)
print(text)  # {"name": "Ann", "langs": ["python", "go"], "admin": false}
back = json.loads(text)
print(back["langs"][0], back == data)  # python True

Let's go through the example line by line:

  1. data is an ordinary dict with a string, a list and False.
  2. json.dumps(data) packs the dict into the string text.
  3. print(text) shows what JSON looks like: almost a Python dict, but False turned into false.
  4. json.loads(text) parses the string and builds new Python objects from it.
  5. The last line prints python True: the rebuilt dict equals the original.

How JSON is written

JSON has its own writing rules, and they are a little stricter than Python's:

  • strings stand only in double quotes;
  • True and False are written as true and false, and None as null;
  • a dict is called an object in JSON, and a list an array.

With indent=2, json.dumps splits the text into lines indented by two spaces. Such a file is convenient to read and edit by hand.

What changes on the way

Here the moving analogy ends: a wardrobe is put together exactly as it was, while data sometimes arrive different. JSON knows only objects, arrays, strings, numbers, true, false and null. So a tuple goes out as an array and returns as a list, and an object's keys are always strings — the number 1 in a key becomes the string "1":

Python
import json

data = {1: "one", "pair": (1, 2)}
back = json.loads(json.dumps(data))
print(back)  # {'1': 'one', 'pair': [1, 2]}
print([1, 2] == (1, 2), back == data)  # False False

Strings, numbers, lists and dicts with string keys come back the same as they left. A list never equals a tuple, even with the same elements, so back and data are no longer equal.

JSON does not accept a set at all: json.dumps({1, 2}) raises TypeError: Object of type set is not JSON serializable. Before packing, a set is turned into a list, for example with sorted.

JSON and files

Files have a pair of functions without the s at the end:

  • json.dump(data, f) writes the data to an open file;
  • json.load(f) reads it from the file.

That is how a program keeps settings between runs. The browser running the course exercises has none of your files, so the exercises work with strings and json.loads.

Common mistake

A JSON string was written with single quotes, as in Python:

Python
import json

settings = json.loads("{'theme': 'dark'}")  # ✗
TEXT
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

The end of the message points at the error: the character at index 1, where JSON expected a double quote. JSON accepts strings only in double quotes: '{"theme": "dark"}'. The class json.JSONDecodeError inherits from ValueError, so except ValueError also catches invalid JSON.

Key points

  • json.dumps turns data into a JSON string, and json.loads builds new objects from a string.
  • In JSON, strings stand only in double quotes, and True, False and None are written as true, false and null.
  • A tuple comes back as a list, a number key as a string, and a set cannot be written to JSON.
  • Invalid JSON raises json.JSONDecodeError, a subclass of ValueError.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way