Самый надежный способ узнать, что делает csv.reader
, - прочитать исходный текст. См. _csv.c
, строки 773 и далее. Вы увидите, что объект reader имеет указатель на базовый итератор (обычно файловый итератор), и он вызывает PyIter_Next
каждый раз, когда ему нужна другая строка. Поэтому он не читает вперед и не кэширует иным образом загружаемые данные.
Другой способ выяснить, что делает csv.reader
, - создать объект фиктивного файла, который может сообщать о запросах. Например:
class MockFile:
def __init__(self): self.line = 0
def __iter__(self): return self
def next(self):
self.line += 1
print "MockFile line", self.line
return "line,{0}".format(self.line)
>>> r = csv.reader(MockFile())
>>> next(r)
MockFile line 1
['line', '1']
>>> next(r)
MockFile line 2
['line', '2']
Это подтверждает то, что мы узнали из чтения исходного кода csv
: он запрашивает следующую строку у нижележащего итератора только тогда, когда вызывается его собственный метод next
.
Джон ясно дал понять (см. Комментарии), что его беспокоит то, будет ли csv.reader
поддерживать строки живыми, предотвращая их сборку менеджером памяти Python.
Опять же, вы можете либо прочитать код (самый надежный), либо попробовать эксперимент. Если вы посмотрите на реализацию Reader_iternext
в _csv.c
, вы увидите, что lineobj
- это имя, данное объекту, возвращаемому базовым итератором, и есть вызов Py_DECREF(lineobj)
на каждом пути через код , Так что csv.reader
не поддерживает lineobj
в живых.
Вот эксперимент, чтобы подтвердить это.
class FinalizableString(string):
"""A string that reports its deletion."""
def __init__(self, s): self.s = s
def __str__(self): return self.s
def __del__(self): print "*** Deleting", self.s
class MockFile:
def __init__(self): self.line = 0
def __iter__(self): return self
def next(self):
self.line += 1
return FinalizableString("line,{0}".format(self.line))
>>> r = csv.reader(MockFile())
>>> next(r)
*** Deleting line,1
['line', '1']
>>> next(r)
*** Deleting line,2
['line', '2']
Итак, вы можете видеть, что csv.reader
не цепляется за объекты, которые он получает от своего итератора, и если ничто иное не поддерживает их, то они своевременно собираются в мусор.
У меня такое ощущение, что в этом вопросе есть что-то большее, чего вы нам не говорите. Не могли бы вы объяснить, почему вас это беспокоит?