В прежних версиях Python принятым способом построчного чтения информации из файла в цикле for было чтение файла в список, а затем обход этого списка в цикле:
>>> file = open(‘data.txt’)
>>> for line in file.readlines(): # НЕ ДЕЛАЙТЕ ТАК БОЛЬШЕ!
… print(line, end=’’)
Если вы уже изучили основы языка с помощью других книг, таких как «Изучаем Python», возможно, вы знаете, что того же результата можно добиться с меньшими усилиями — и для вас, и для вашего компьютера. В последних версиях Python объект файла включает итератор, который при каждом обращении извлекает только одну строку из файла в любых итерационных контекстах, включая циклы for и генераторы списков. Практическая выгода заключается в том, что теперь нет необходимости вызывать метод readlines в цикле for, чтобы построчно просканировать содержимое файла, — итератор читает строки автоматически:
>>> file = open(‘data.txt’)
>>> for line in file: # нет необходимости вызывать readlines
… print(line, end=’’) # итератор каждый раз читает следующую строку
Hello file world!
Более того — теперь файл можно открывать непосредственно в инструкции цикла, как временный, который будет автоматически закрыт сборщиком мусора после выхода из цикла (так как часто цикл — это единственная ссылка на объект файла):
>>> for line in open(‘data.txt’): # еще короче: временный объект файла … print(line, end=’’) # будет закрыт при утилизации автоматически
Hello file world! Bye file world.
Кроме того, такая форма обхода строк в файле не вызывает загрузку всего содержимого файла в список строк, поэтому она более экономно расходует память при работе с большими текстовыми файлами. По этой причине данный способ построчного чтения файлов является наиболее предпочтительным на сегодняшний день. Если вам интересно узнать, что же в действительности происходит внутри цикла for, вы можете попробовать использовать итератор вручную. Итератор — это всего лишь метод __next__ (вызываемый встроенной функцией next), который своим поведением напоминает метод readline, за исключением того, что по достижении конца файла методы чтения возвращают пустую строку, а итератор возбуждает исключение, чтобы прервать итерации:
>>> file = open(‘data.txt’) # методы чтения: пустая строка в конце файла
>>> file.readline()
‘Hello file world!\n’
>>> file.readline()
‘Bye file world.\n’
>>> file.readline()
>>> file = open(‘data.txt’) # итераторы: исключение в конце файла
>>> file.__next__() # не нужно предварительно вызывать iter(file),
‘Hello file world!\n’ # потому что файлы имеют собственные итераторы
>>> file.__next__()
‘Bye file world.\n’
>>> file.__next__()
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
StopIteration
Интересно отметить, что итераторы автоматически используются во всех итерационных контекстах, включая конструктор списка, генераторы списков, функцию map и оператор in проверки на вхождение:
>>> open(‘data.txt’).readlines() # всегда читает строки
[‘Hello file world!\n’, ‘Bye file world.\n’]
>>> list(open(‘data.txt’)) # выполняет обход строк
[‘Hello file world!\n’, ‘Bye file world.\n’]
>>> lines = [line.rstrip() for line in open(‘data.txt’)] # генераторы
>>> lines
[‘Hello file world!’, ‘Bye file world.’]
>>> lines = [line.upper() for line in open(‘data.txt’)] # произв. действия
>>> lines
[‘HELLO FILE WORLD!\n’, ‘BYE FILE WORLD.\n’]
>>> list(map(str.split, open(‘data.txt’))) # применение функции
[[‘Hello’, ‘file’, ‘world!’], [‘Bye’, ‘file’, ‘world.’]]
>>> line = ‘Hello file world!\n’
>>> line in open(‘data.txt’) # проверка на вхождение
True
На первый взгляд итераторы могут показаться не слишком представительными, но они предоставляют множество способов, упрощающих жизнь разработчиков программ на языке Python.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011