Reference · module 15
Files and JSON
Everything this module explains, on one page.
Reading a file
Get the contents of a file into your program.
- with open("notes.txt") as f: opens a file and gives it the name f for the length of the indented block. Inside it, f.read() hands back the whole contents as one string.
- The with is what closes it again — at the end of the block, and also if something raises inside. It is the finally from the last module, written as one word by somebody who got tired of writing it.
- For lines rather than one lump, loop the file directly: for line in f: gives one line per pass, and each still carries the newline it ended with. line.strip() takes that off.
The mistake you are about to make
f = open("notes.txt")
with open("notes.txt") as f:
Opening and reading without with works perfectly well. Closing is then your job, and the first error inside leaves the file open. With closes it either way.
Writing a file
Put something on disk, and not destroy what was there.
- open takes a second argument, the mode. "r" is read and is the default; "w" is write; "a" is append. The one you leave out is the one that has been deciding for you.
- "w" empties the file the moment it opens, before you write anything. That is not a warning about a rare case: opening a full file in "w" and then failing leaves you with nothing.
- "a" adds to the end and keeps what was there, which is what a log wants. And f.write() adds no newline — unlike print, it puts down exactly the characters you gave it.
The mistake you are about to make
open("notes.txt", "w") to add a line
open("notes.txt", "a")
"w" reads as write, and appending feels like part of writing. It empties the file the moment it opens, before anything is written. Appending is "a".
JSON
Turn Python data into text and back.
- A file holds text, and your data is dictionaries and lists. JSON is the agreed way between them: json.dumps(data) makes a string, json.loads(text) reads one back.
- The s is for string, and it is the whole difference: dumps hands you text, dump writes it straight to a file. Same for loads and load. Four names, two jobs.
- Dictionaries, lists, strings, numbers and booleans survive the trip. A tuple comes back as a list, and True becomes true in the text — JSON has its own spelling, which is why it is not Python.
The mistake you are about to make
json.dump(data)
json.dumps(data)
The names differ by one letter, and that letter means string: dumps returns text, dump writes to a file and needs a second argument. Same for loads and load.
Files that are not there
Handle a missing file instead of crashing on it.
- Opening a file that does not exist raises FileNotFoundError. It is the commonest error a program meets in the wild, because a file is the one thing your program does not control.
- Two ways to deal with it, and Python prefers the second: check first with os.path.exists, or just try and catch. Trying is preferred because between the check and the open, the file can vanish.
- So the shape is: try to read it, and in the except use a default. A program that starts with empty settings beats one that will not start at all.
The mistake you are about to make
os.path.exists first, then open
open in a try, with a fallback in the except
Checking before opening looks tidier. The file can vanish between the check and the open, which is why Python prefers trying and catching.
Text into data
Turn lines of a file into something you can work with.
- "a,b,c".split(",") gives ["a", "b", "c"]. It cuts a string wherever it finds the separator and hands back a list, which is how a line of a file becomes fields.
- ",".join(items) goes the other way: a list of strings into one string, with the separator between them. Note which side it is called on — the separator, not the list.
- Together with the last three lessons that is a whole small program: read the lines, split each one, build the dictionaries, and json.dumps the lot back out. Nothing new is needed for it.
The mistake you are about to make
line.split(",")
line.strip().split(",")
Every line from a file still carries the newline it ended with, and it sticks to the last field. Strip it off before splitting, not after.