这可能是一个愚蠢的问题,但是我对以下内容感到困惑:我从csv模块的DictReader类中创建了一个reader对象。
以下代码返回错误,因为csv文件已经关闭,因为没有缩进for循环:
import csv
with open(file) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row)
返回此错误:
ValueError: I/O operation on closed file.
但是,我能够运行命令来获取读者的属性,例如:
reader.fieldnames
reader.line_num
这是什么逻辑?我对为什么我可以访问读者的属性却不再遍历它的属性感到困惑。另外,我还以为一旦分配:
reader = csv.DictReader(csvfile)
即使关闭文件,我也应该能够访问阅读器的内容。
csv.DictReader
(以及csv.reader
)也以文件句柄对象为参数而构建。它不会复制句柄,也不会一次读取文件的全部内容,等等。
[退出退出with
块时,此文件句柄已关闭,当csv.DictReader
对象尝试访问它时,它偶然遇到了“关闭的文件”异常。请注意,with
块适用于原始文件句柄,而不适用于csv.DictReader
对象。
csv.DictReader
对象仍然存在并且有效,但是由于其源文件句柄已失效,因此不再可用于读取数据。
与下面的简单示例没什么不同:
class Foo:
def __init__(self,source):
self.source = source
def bar(self):
print(self.source)
lst = [1,2,3]
f = Foo(lst)
f.bar() # prints [1, 2, 3]
lst.clear()
f.bar() # prints []
上面,一旦清除lst
,即使f
对象本身仍然有效,f
对象也会失去打印列表的能力。
如果要保留内容,则要方便使用阅读器属性,必须在单独的list
对象中强制对文件进行迭代:
reader = csv.DictReader(csvfile)
contents = list(reader)