Python: 不需要csv.close()?
我正在使用CSV模块来读取一个用制表符分隔的文件。下面是我的代码:
z = csv.reader(open('/home/rv/ncbi-blast-2.2.23+/db/output.blast'), delimiter='\t')
但是当我在脚本的最后加上Z.close()时,出现了一个错误,提示“csv.reader对象没有'close'这个属性”。
z.close()
那么我该怎么关闭“Z”呢?
3 个回答
你并不是关闭 reader()
方法的结果,而是关闭 open()
方法的结果。所以,你需要用两条语句:foo=open(...); bar=csv.reader(foo)
。然后你可以调用 foo.close()
来关闭文件。
把本来可以用两条语句写得更清晰、更好理解的东西硬要写成一条,是不会得到额外的分数的。
你不需要直接关闭CSV读取器;相反,你应该关闭正在使用的文件对象。比如,在你的例子中,你可以这样做:
f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast')
z = csv.reader(f, delimiter='\t')
...
f.close()
如果你使用的是较新的Python版本,可以使用with语句,比如:
with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f:
z = csv.reader(f, delimiter='\t')
...
这样做的好处是,即使你在with块中抛出异常或者提前返回,f
也会被关闭。而在之前的例子中,如果出现这种情况,文件可能会一直保持打开状态。换句话说,这基本上等同于一个try/finally块,比如:
f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast')
try:
z = csv.reader(f, delimiter='\t')
...
finally:
f.close()
这个“读取器”其实就是一个解析器。当你请求一行数据时,它会把读取的工作交给底层的 file
对象,然后把结果转换成一组字段。这个读取器本身并不管理任何需要在使用完后清理的资源,所以你不需要去关闭它;这样做没有意义。
不过,你要确保关闭底层的 file
对象,因为它确实管理着一个资源(一个打开的文件描述符),这个资源是需要清理的。下面是关闭的方法:
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
如果你不太了解 with
语句,可以把它理解为把内容放在一个 try...finally
块里,最后会在 finally
部分关闭文件。
希望这不成问题(如果成问题,那你真的需要更新到更新版的 Python),不过 with
语句是在 Python 2.5 中引入的,在那个版本中你需要用 __future__
导入来启用它。如果你使用的是更老的 Python 版本,那你就得自己用 try...finally
来关闭文件。
感谢 Jared 指出关于 with
语句的兼容性问题。