[ACCEPTED]-Using "with" statement for CSV files in Python-with-statement

Accepted answer
Score: 21

The primary use of with statement is an exception-safe 9 cleanup of an object used in the statement. with makes 8 sure that files are closed, locks are released, contexts 7 are restored, etc.

Does csv.reader have things to cleanup 6 in case of exception?

I'd go with:

with open("myfile.csv") as f:
    for row in csv.reader(f):
        # process row

You don't 5 need to submit the patch to use csv.reader and with statement 4 together.

import contextlib

Help on function contextmanager 3 in module contextlib:

contextmanager(func)
    @contextmanager decorator.

Typical usage:

    @contextmanager
    def some_generator(<arguments>):
        <setup>
        try:
            yield <value>
        finally:
            <cleanup>

This makes this:

    with some_generator(<arguments>) as <variable>:
        <body>

equivalent 2 to this:

    <setup>
    try:
        <variable> = <value>
        <body>
    finally:
        <cleanup>

Here's a concrete example how I've 1 used it: curses_screen.

Score: 4

Yes. The second way is correct.

As to why? Who 4 ever knows. You're right, it's probably 3 an easy change. It's not as high priority 2 as other things.

You can easily make your 1 own patch kit and submit it.

Score: 2

The problem is csv.reader doesn't really 6 manage a context. It can accept any iterable, not 5 just a file. Therefore it doesn't call 4 close on its input (incidentally if it did 3 you could use contextlib.closing). So it's 2 not obvious what context support for csv.reader 1 would actually do.

Score: 1
import csv

class CSV(object):
    def __init__(self,path,mode):
        self.path = path
        self.mode = mode
        self.file = None

    def __enter__(self):
        self.file = open(self.path,self.mode)
        if self.mode == 'r':
            return csv.reader(self.file)
        elif self.mode == 'w':
            return csv.writer(self.file)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()   

with CSV('data.csv','r') as reader:
    for row in reader:
        print row

0

Score: 0

It's easy to create what you want using 1 a generator function:


import csv
from contextlib import contextmanager

@contextmanager
def opencsv(path):
   yield csv.reader(open(path))

with opencsv("myfile.csv") as reader:
   # do stuff with your csvreader

More Related questions