csv模块=> DictReader类Reader对象:为什么我不能在关闭文件的情况下通过Reader Object进行迭代,但是我可以访问其属性?

问题描述 投票:1回答:1

这可能是一个愚蠢的问题,但是我对以下内容感到困惑:我从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)

即使关闭文件,我也应该能够访问阅读器的内容。

python csv filereader
1个回答
1
投票

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)
© www.soinside.com 2019 - 2024. All rights reserved.