Reading and Writing Text Files
18 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)Variables vanish when a program ends. A file keeps data on disk, so the next run can read it again. Python opens text files with the built-in open, and the with statement makes sure the file is closed afterwards.
Open a file with with
with statement runs a block of code and then cleans up, even if an error happens inside. For files it closes the file when the block ends.
A program that forgets to close a file can lose data or lock the file. Put the work inside a with block. Python opens the file, runs your lines, then closes it for you.
with open("marks.txt", "w") as f: f.write("Asha 82\n") f.write("Ravi 67\n")
with open("marks.txt") as f: text = f.read()print(text, end="")Example 1 · Save and read order totals
with open("orders.txt", "w") as f: f.write("A101 250\nA102 400\n")
with open("orders.txt") as f: print(f.read(), end="")A101 250 A102 400
What this code does
"w"createsorders.txtin the current folder.end=""stops print from adding a second newline after the text.
open("marks.txt", "w") creates the file for writing. as f names the file object. f.write adds text and does not add a newline, so each line ends with \n. f.read() returns the whole file as one string.
Modes and encoding
Encoding is the rule that turns characters into bytes on disk. UTF-8 handles every language, so write encoding="utf-8" and the text reads the same on every computer.
The second argument of open is the mode. It says what you plan to do. The encoding argument says how characters become bytes.
with open("log.txt", "w", encoding="utf-8") as f: f.write("Order 1 placed\n")
with open("log.txt", "a", encoding="utf-8") as f: f.write("Order 2 placed\n")
with open("log.txt", encoding="utf-8") as f: print(f.read(), end="")Example 2 · Append keeps old lines
with open("log.txt", "w") as f: f.write("start\n")with open("log.txt", "a") as f: f.write("next\n")with open("log.txt") as f: print(f.read().splitlines())['start', 'next']
What this code does
- The second
openuses"a", sostartis still there. splitlines()returns the lines as a list without the newlines.
Example 3 · Unicode text with utf-8
with open("names.txt", "w", encoding="utf-8") as f: f.write("Zoë\nÅsa\n")with open("names.txt", encoding="utf-8") as f: names = f.read().split()print(ascii(names))print(len(names[0]))['Zo\xeb', '\xc5sa'] 3
What this code does
- UTF-8 stores letters such as
ëandÅsafely.asciishows them as escapes, so the output looks the same on every screen. lencounts characters, not bytes, soZoëhas length 3.
Mode "r" reads (the default), "w" writes and erases what was there, and "a" appends to the end. The second open used "a", so both lines survive. Using "w" there would have deleted line 1.
Reading line by line
A big file may not fit in memory, and often you want one record at a time. A file object is a sequence of lines, so you can loop over it directly.
with open("marks.txt", "w") as f: f.write("Asha 82\nRavi 67\nMeena 91\n")
total = 0with open("marks.txt") as f: for line in f: name, mark = line.split() total += int(mark) print(name, mark)print("Total:", total)Example 4 · Total marks from a file
with open("marks.txt", "w") as f: f.write("Asha 82\nRavi 67\nMeena 91\n")
total = 0with open("marks.txt") as f: for line in f: name, mark = line.split() total += int(mark)print(total)240
What this code does
- Each line is split into a name and a mark, and the mark becomes an
int. - Only one line is in memory at a time.
Each line still ends with a newline. split() with no argument cuts on spaces and drops that newline, so mark is clean text and int(mark) works. The loop reads one line at a time.
Writing many lines
Calling write once per line gets long. print can write to a file too, and it adds the newline for you. Use splitlines() to turn the text back into a list of lines.
items = ["Pen", "Book", "Bag"]with open("items.txt", "w") as f: for item in items: print(item, file=f)
with open("items.txt") as f: lines = f.read().splitlines()print(lines)print(item, file=f) sends the text to the file instead of the screen. splitlines() removes the line endings, so the list has clean names.
Next step
Check your understanding
10 quick questions