Modules and the standard libraryChapter 74 of 114
JSON
Turn Python data into text and back, for files and APIs.
What JSON is
A text format for structured data. It is how almost every web API sends information, and a good format for configuration:
import json
data = {"name": "Ada", "born": 1815, "fields": ["maths", "computing"]}
text = json.dumps(data)
print(text)
print(type(text).__name__)Output
{"name": "Ada", "born": 1815, "fields": ["maths", "computing"]}
strdumps is "dump to string". The result is text, ready to send or write.
Reading it back
import json
text = '{"name": "Ada", "born": 1815}'
data = json.loads(text)
print(data["name"])
print(type(data).__name__)Output
Ada dict
Four functions, and the s is the only difference:
| Function | Does |
|---|---|
json.dumps(data) | Python to a string |
json.loads(text) | a string to Python |
json.dump(data, file) | Python into an open file |
json.load(file) | an open file to Python |
Files
import json
data = {"name": "Ada", "fields": ["maths"]}
with open("person.json", "w") as f:
json.dump(data, f)
with open("person.json") as f:
loaded = json.load(f)
print(loaded["fields"])Output
['maths']
That really wrote a file, in this page's in-browser filesystem.
Readable output
import json
data = {"name": "Ada", "fields": ["maths", "computing"]}
print(json.dumps(data, indent=2))Output
{
"name": "Ada",
"fields": [
"maths",
"computing"
]
}sort_keys=True orders them, which makes two files comparable:
import json
print(json.dumps({"b": 1, "a": 2}, sort_keys=True))Output
{"a": 2, "b": 1}The type mapping
JSON has fewer types than Python, so a round trip is not always exact:
| Python | JSON |
|---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True / False | true / false |
None | null |
import json
original = {"tuple": (1, 2), "none": None, "yes": True}
text = json.dumps(original)
print(text)
print(json.loads(text)["tuple"])Output
{"tuple": [1, 2], "none": null, "yes": true}
[1, 2]The tuple came back a list. JSON has no tuples.
import json
text = json.dumps({1: "one"})
print(text)
print(json.loads(text))Output
{"1": "one"}
{'1': 'one'}What cannot be converted
Anything JSON has no equivalent for raises TypeError:
import json
from datetime import date
try:
json.dumps({"when": date(2026, 3, 14)})
except TypeError as problem:
print("TypeError:", problem)
print(json.dumps({"when": date(2026, 3, 14).isoformat()}))Output
TypeError: Object of type date is not JSON serializable
{"when": "2026-03-14"}Convert to something JSON understands first — an ISO string for a date — or pass default=str to let dumps stringify anything it does not recognise.
Handling bad input
Text from outside your program may not be valid JSON:
import json
for text in ['{"ok": true}', "not json at all"]:
try:
print(json.loads(text))
except json.JSONDecodeError as problem:
print("bad JSON:", problem.msg)Output
{'ok': True}
bad JSON: Expecting valueNon-English text
import json
data = {"city": "München"}
print(json.dumps(data))
print(json.dumps(data, ensure_ascii=False))Output
{"city": "M\u00fcnchen"}
{"city": "München"}By default dumps escapes anything outside ASCII. Both lines are valid JSON and both load back to exactly the same string, so it only matters when a person is going to read the file. Then ensure_ascii=False is much friendlier.
Test yourself
2 questionsWhat happens to a tuple when it goes through json.dumps and back?
Show the answer
It comes back as a list — JSON has no tuple type, and dictionary keys come back as strings for the same reason.
What is the difference between json.dumps and json.dump?
Show the answer
dumps returns a string; dump writes to an open file — The s is for string. The same pairing applies to loads and load.
RegEx
Find and replace text by pattern rather than by exact match.