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:
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 TrueLet's go through the example line by line:
datais an ordinary dict with a string, a list andFalse.json.dumps(data)packs the dict into the stringtext.print(text)shows what JSON looks like: almost a Python dict, butFalseturned intofalse.json.loads(text)parses the string and builds new Python objects from it.- 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;
TrueandFalseare written astrueandfalse, andNoneasnull;- 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":
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 FalseStrings, 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:
import json
settings = json.loads("{'theme': 'dark'}") # ✗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.dumpsturns data into a JSON string, andjson.loadsbuilds new objects from a string.- In JSON, strings stand only in double quotes, and
True,FalseandNoneare written astrue,falseandnull. - 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 ofValueError.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.