Reputation: 3931
I'm creating a csv.reader
object, setting it as an instance variable, but then when I try to iterate through it I get an error saying I'm trying to operate on a closed file. Is the reader
still linked to the file somehow? I'm assigning it within my with open(blah)
block, so I'm confused as to why this is happening.
Here is my code:
def __init__(self, infile, header_file, transact_file):
self.infile = infile
self.header_of = header_file
self.transact_of = transact_file
def create_reader(self):
"""Create a csv reader."""
with open(self.infile, 'r') as inf:
logging.info('Infile name: {0}'.format(inf))
self.csv_reader = reader(inf, quotechar='"')
def parse_headers(self):
"""Separate header files ("H", "S") from transaction files."""
headers = []
transactions = []
for row in self.csv_reader:
row_type = row[0]
logging.info('Row type is: {0}'.format(row_type))
if row_type == 'H':
logging.info('Row added to header list.')
headers.append(row)
elif row_type == 'S':
if row not in headers:
logging.info('Row added to header list.')
headers.append(row)
else:
logging.info('Row added to transaction list.')
transactions.append(row)
# Debugging and verification
logging.info('Header list contains: {0}'.format('\n'.join([str(header) for header
in headers])))
logging.info('Transaction list contains: {0}'.format(
'\n'.join([str(trans) for trans in transactions])))
Here is my error stack:
Traceback (most recent call last): x
File "./gen_pre.py", line 155, in <module> x
main() x
File "./gen_pre.py", line 25, in main x
parser.run_process() x
File "./gen_pre.py", line 140, in run_process x
self.parse_headers() x
File "./gen_pre.py", line 68, in parse_headers x
for row in self.csv_reader: x
ValueError: I/O operation on closed file
Upvotes: 2
Views: 1628
Reputation: 11804
Context managers are great because they automatically close files for you. Instead of manually opening and closing the file, you could read the whole file and pass a list of the rows to the CSV reader:
def create_reader(self):
"""Create a csv reader."""
with open(self.infile, 'r') as inf:
logging.info('Infile name: {0}'.format(inf))
file_data = inf.readlines()
self.csv_reader = reader(file_data, quotechar='"')
The csv.reader
object will accept anything it can iterate over, so a list of each line in the file (from readlines
) will work fine.
Upvotes: 2
Reputation: 142631
with
automatically closes the file when you leave the block.
You have to do
self.inf = open(self.infile, 'r')
self.csv_reader = reader(self.inf, quotechar='"') # self.inf
and you will have to close the file manually.
def close_reader(self):
self.csv_reader.close()
self.inf.close()
Upvotes: 3