csv module => DictReader class Reader Object: почему я не могу перебрать объект Reader с закрытым файлом, но могу получить доступ к его атрибутам? - PullRequest
1 голос
/ 26 апреля 2020

Это может быть глупый вопрос, но меня смущает следующее: я создал объект reader из класса DictReader модуля csv.

Следующий код возвращает ошибку, поскольку файл csv уже закрыто, так как for для l oop не имеет отступа:

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

Что такое лог c для этого? Я не понимаю, почему я могу получить доступ к атрибутам читателя, но больше не перебираю его. Кроме того, я бы подумал, что как только я назначу:

reader = csv.DictReader(csvfile)

, я смогу получить доступ к содержимому считывателя даже при закрытом файле.

1 Ответ

2 голосов
/ 26 апреля 2020

csv.DictReadercsv.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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...