Python: No csv.close()?
I'm using the CSV module to read a tab delimited file. Code below:
z = csv.reader(open('/home/rv/ncbi-blast-2.2.23+/db/output.blast'), delimiter='\t')
But when I add Z.close() to end of my script i get and error stating "csv.reader' object has no attribute 'close'"
z.close()
So how do i close "Z"?
Solution 1:
The reader is really just a parser. When you ask it for a line of data, it delegates the reading action to the underlying file
object and just converts the result into a set of fields. The reader itself doesn't manage any resources that would need to be cleaned up when you're done using it, so there's no need to close it; it'd be a meaningless operation.
You should make sure to close the underlying file
object, though, because that does manage a resource (an open file descriptor) that needs to be cleaned up. Here's the way to do that:
with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f:
z = csv.reader(f, delimiter='\t')
# do whatever you need to with z
If you're not familiar with the with
statement, it's roughly equivalent to enclosing its contents in a try...finally
block that closes the file in the finally
part.
Hopefully this doesn't matter (and if it does, you really need to update to a newer version of Python), but the with
statement was introduced in Python 2.5, and in that version you would have needed a __future__
import to enable it. If you were working with an even older version of Python, you would have had to do the closing yourself using try...finally
.
Thanks to Jared for pointing out compatibility issues with the with
statement.
Solution 2:
You do not close CSV readers directly; instead you should close whatever file-like object is being used. For example, in your case, you'd say:
f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast')
z = csv.reader(f, delimiter='\t')
...
f.close()
If you are using a recent version of Python, you can use the with statement, e.g.
with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f:
z = csv.reader(f, delimiter='\t')
...
This has the advantage that f
will be closed even if you throw an exception or otherwise return inside the with-block, whereas such a case would lead to the file remaining open in the previous example. In other words, it's basically equivalent to a try/finally block, e.g.
f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast')
try:
z = csv.reader(f, delimiter='\t')
...
finally:
f.close()
Solution 3:
You don't close the result of the reader()
method, you close the result of the open()
method. So, use two statements: foo=open(...); bar=csv.reader(foo)
. Then you can call foo.close()
.
There are no bonus points awarded for doing in one line that which can be more readable and functional in two.