LambdaLabTM
Computer Science · Class 12 · CSV Files
CSV filesopen & close⏱️ 12 min read

Opening & Closing a CSV File

There is no new function in this lesson. A CSV is a text file, so you open it with the open() you learned in the Text Files chapter and close it with the same close(). What is worth a lesson is the two places students go wrong: reaching for a binary mode out of habit, and leaving out the one extra argument.

The lesson these programs practiseThe Open Modes — r, w and a, in full

1The call, in full

f = open('marks.csv', 'w', newline='')
the address

A name, or a whole path. Exactly as in every other open().

a text mode

'r', 'w' or 'a'. No 'b' anywhere — a CSV is a text file.

newline=''

Stops an extra blank line appearing between the rows.

The first two are old news. The third one is new, and this lesson only asks you to type it — the reason it is there gets a lesson of its own once you have seen the file it repairs.

A rule you can follow before you understand it
Put newline='' in every open() call that involves a CSV file, reading or writing. It never does harm, and leaving it out causes a bug that is hard to spot. The why is two lessons away.

2The three modes you need

Let's Recap!
ModeIf the file existsIf it does notUsed for
'r'opens it for readingFileNotFoundErrorreading records
'w'empties it completelycreates itcreating a file from scratch
'a'keeps it, writes at the endcreates itadding records to an existing file
'w' empties the file before you write a thing
The moment open('marks.csv', 'w') runs, every record already in marks.csv is gone — even if the program crashes on the next line and writes nothing. When you want to add a record to a file that already has some, 'a' is the mode, not 'w'.

3Never 'rb' or 'wb'

You have just spent a chapter adding b to every mode. Do not add it here. A CSV file holds text, so it is opened in text mode, and the error you get for forgetting has nothing in it about modes:

wrong_mode.py
import csv

f = open('marks.csv', 'wb')
w = csv.writer(f)
w.writerow(['Ravi', 78])
f.close()
Output
Traceback (most recent call last):
  File "wrong_mode.py", line 5, in <module>
    w.writerow(['Ravi', 78])
TypeError: a bytes-like object is required, not 'str'

Read the message from the file's point of view and it makes sense: 'wb' told the file to accept bytes, and the csv writer handed it a string. The fix is on line 3, three lines above where Python stopped.

binary files — last chapter
open('marks.dat', 'wb')

pickle writes bytes, so the file must accept bytes.

csv files — this chapter
open('marks.csv', 'w', newline='')

The csv writer writes text, so the file must accept text.

4Closing it — and what happens if you do not

close() is called on the file. Not on the writer, not on the reader — those have no close() and need none.

closing.py
import csv

f = open('marks.csv', 'w', newline='')
w = csv.writer(f)
w.writerow(['Ravi', 78])

f.close()      # correct — close the file
# w.close()    # wrong — a writer has no close()

Everything the closing lesson taught still applies, because it is the same file object underneath. What writerow() writes sits in a buffer in memory; close() is what pushes it onto the disk. Use the writer after that and Python refuses:

too_late.py
import csv

f = open('marks.csv', 'w', newline='')
w = csv.writer(f)
f.close()

w.writerow(['Ravi', 78])
Output
Traceback (most recent call last):
  File "too_late.py", line 7, in <module>
    w.writerow(['Ravi', 78])
ValueError: I/O operation on closed file.

5Letting with close it

The with clause works here exactly as it does for a text file, and for the same reason: the file is closed when the block ends, even if something goes wrong inside it.

with_csv.py
import csv

with open('marks.csv', 'r', newline='') as f:
    for row in csv.reader(f):
        print(row)

print('closed?', f.closed)
Output
['Roll', 'Name', 'Marks']
['1', 'Ravi', '78']
['2', 'Meera', '91']
['3', 'Amit', '65']
closed? True
Note
The csv.reader(f) line goes inside the block. It needs an open file, and outside the block there is not one.

6When the file is not there

Opening a CSV for reading that does not exist fails on the open() line, before the csv module is involved at all:

missing.py
import csv

f = open('results.csv', 'r', newline='')
r = csv.reader(f)
for row in r:
    print(row)
f.close()
Output
Traceback (most recent call last):
  File "missing.py", line 3, in <module>
    f = open('results.csv', 'r', newline='')
FileNotFoundError: [Errno 2] No such file or directory: 'results.csv'

The repair is the same one the paths lesson gave you — wrap it in try:

safe_open.py

7The whole round trip

Write a file and read it back, with nothing in it you have not met. Every line after import csv is either an open(), a close(), or one of the two new objects:

round_trip.py
Close before you read
Note the f.close() in the middle. The same handle cannot be used for both jobs — it was opened in 'w' — and the rows may still be sitting in the buffer until that close runs.

8Recap

open() is unchanged

The same function, the same first two arguments. There is no csv.open().

Text modes only

'r', 'w', 'a'. Adding a b gives TypeError: a bytes-like object is required, not 'str'.

newline='' every time

In every open() that touches a CSV. Two lessons from now you will see what it repairs.

'w' empties, 'a' adds

Opening in 'w' wipes the file the instant it runs, records and header alike.

Close the file

f.close(), never w.close(). Using a writer afterwards raises ValueError: I/O operation on closed file.

with closes it for you

Put the csv.reader() or csv.writer() line inside the block, where the file is open.

✍️ Now write these yourself
  1. 1

    Open a CSV in 'wb' on purpose and read the error. Note which line Python blames.

    Hint · It blames the writerow(), but the mistake is up on the open() line.

  2. 2

    Call f.close() and then w.writerow().

    Hint · ValueError: I/O operation on closed file.

  3. 3

    Write the round-trip program using with for both halves.

    Hint · Two blocks, one after the other. No close() anywhere.

  4. 4

    Open an existing CSV in 'w', write nothing, close it, and look at the file.

    Hint · Empty. That is what 'w' does the moment it opens.

Quick Check

Which mode should you use to open a CSV file for writing?

Quick Check

What do you call close() on?

Quick Check

You want to add one record to a CSV that already holds fifty. Which mode?

Quick Check

Where should the csv.reader(f) line go when you use a with block?