Автор оригинала: Frank Hofmann.
Чтение файлов с помощью Python
Чтобы работать с сохраненными данными, обработка файлов относится к основным знаниям каждого профессионального программиста Python. Начиная с самого раннего выпуска, чтение и запись данных в файлы являются встроенными функциями Python. По сравнению с другими языками программирования, такими как C или Java, он довольно прост и требует всего нескольких строк кода. Кроме того, для этого не нужно загружать дополнительный модуль.
Основы работы с файлами в Python
Наиболее распространенными методами работы с файлами являются open()
для открытия файла, seek()
для установки текущего положения файла при заданном смещении и close()
для закрытия объекта file, когда вы закончите его использовать. Метод open()
возвращает дескриптор файла, представляющий файловый объект, используемый для доступа к файлу для чтения, записи или добавления.
При открытии файла для чтения Python должен точно знать, как файл должен быть открыт системой. Доступны два режима доступа – чтение и чтение в двоичном режиме. Соответствующие флаги используются r
и rb
и должны быть указаны при открытии файла с помощью встроенного метода open ()
. Первый режим включает в себя интерпретацию специальных символов, таких как “CR” (возврат каретки) и “LF” (перевод строки) для представления разрывов строк, тогда как двоичный режим позволяет считывать данные в необработанном режиме-где данные хранятся как есть без дальнейшей интерпретации.
Как только вы откроете файл, метод open()
вернет вам файловый объект. Эти файловые объекты имеют такие методы, как read ()
, readline ()
, write ()
, tell ()
и seek()
. Хотя некоторые файловые объекты (или файлоподобные объекты) имеют больше методов, чем перечисленные здесь, они являются наиболее распространенными. Не все файловые объекты должны реализовывать все файловые методы.
Примеры
В этой статье мы объясним, как читать файлы с помощью Python на примерах. Некоторые примеры включают чтение файла построчно, как фрагмент (определенное количество строк за раз), и чтение файла за один раз. Кроме того, мы покажем вам способ чтения определенной строки из файла, только без поиска всего файла.
Чтение файла Строка за строкой
Первый пример вдохновлен двумя языками программирования C и C++. Это довольно просто, откройте файл с помощью метода open ()
, прочитайте файл строка за строкой с помощью метода readline()
и выведите строку сразу после чтения. Здесь используется цикл while
, который непрерывно считывает данные из файла до тех пор, пока метод readline()
продолжает возвращать данные. В случае достижения конца файла (EOF) цикл while
останавливается и файловый объект закрывается, освобождая ресурсы для использования другими программами.
# define the name of the file to read from filename = "test.txt" # open the file for reading filehandle = open(filename, 'r') while True: # read a single line line = filehandle.readline() if not line: break print(line) # close the pointer to that file filehandle.close()
Листинг 1
Как вы, возможно, заметили в Листинге 1 мы явно открыли и закрыли файл (строки 5 и 14 соответственно). Хотя интерпретатор Python автоматически закрывает открытые файлы в конце выполнения программы Python, явное закрытие файла через close()
является хорошим стилем программирования и не должно быть забыто.
В качестве улучшения в Python 2.3 был введен удобный протокол итератора. Это позволяет упростить цикл readline
следующим образом:
# define the name of the file to read from filename = "test.txt" for line in open(filename, 'r'): print(line)
Листинг 2
Здесь используется цикл for
в сочетании с итератором in
. Файл открывается в строке 4 из Листинга 2 . Текущая строка идентифицируется с помощью итератора in
, считывается из файла, а его содержимое выводится в stdout
в строке 5. Python покрывает открытие и закрытие файла для вас, когда он выпадает из области видимости. Хотя это неэффективно, это позволяет вам больше не иметь дела с дескрипторами файлов.
К сожалению, приведенный выше код менее явен и полагается на внутреннюю сборку мусора Python для обработки закрытия файла. Введенная в Python 2.5 команда with
еще больше инкапсулирует весь процесс, а также обрабатывает открытие и закрытие файлов только один раз на протяжении всего блока кода. В листинге 3 показано, как использовать команду with
.
# define the name of the file to read from filename = "test.txt" with open(filename, 'r') as filehandle: for line in filehandle: print(line)
Листинг 3
Комбинация оператора with
и команды open()
открывает файл только один раз (строка 4). В случае успеха выполняется цикл for
, и содержимое строки выводится на stdout
(строки 5 и 6).
Кроме того, использование оператора with
имеет побочный эффект. Внутренне интерпретатор Python создает блок try
– |/finally -для инкапсуляции чтения из файла.
Листинг 4 показывает, что по существу происходит внутри Python с блоками кода with :
try: filehandle = open(filename, 'r') # do something finally: filehandle.close()
Листинг 4
Чтение файла в виде фрагментов строк
До сих пор мы обрабатывали файл строка за строкой. Это довольно медленно для огромных файлов и может быть улучшено путем чтения нескольких строк одновременно. Для этого в игру вступает метод slice()
из модуля itertools . Кроме того, он работает как итератор и возвращает фрагмент данных, состоящий из n
строк. В конце файла результат может быть короче, и, наконец, вызов вернет пустой список.
from itertools import islice # define the name of the file to read from filename = "test.txt" # define the number of lines to read number_of_lines = 5 with open(filename, 'r') as input_file: lines_cache = islice(input_file, number_of_lines) for current_line in lines_cache: print (current_line)
Листинг 5
Чтение определенной строки из файла
Используя методы, показанные выше, мы также можем выполнять другие полезные действия, такие как чтение определенной строки из файла. Для этого мы используем счетчик и печатаем соответствующую строку, когда приходим к ней во время итерации по файлу.
# define the name of the file to read from filename = "test.txt" # define the line number line_number = 3 print ("line %i of %s is: " % (line_number, filename)) with open(filename, 'r') as filehandle: current_line = 1 for line in filehandle: if current_line == line_number: print(line) break current_line += 1
Листинг 6
Листинг 6 должен быть простым для понимания, но он немного длиннее, чем предыдущие примеры. Его можно сократить с помощью модуля linecache . Листинг 7 показывает, как упростить код с помощью метода getline ()
. Если запрошенный номер строки выпадает из диапазона допустимых строк в файле, то метод getline()
возвращает пустую строку.
# import linecache module import linecache # define the name of the file to read from filename = "test.txt" # define line_number line_number = 3 # retrieve specific line line = linecache.getline(filename, line_number) print ("line %i of %s:" % (line_number, filename)) print (line)
Листинг 7
Чтение всего файла сразу
И последнее, но не менее важное, мы рассмотрим совсем другой случай, чем в предыдущем примере, – чтение всего файла за один раз. Имейте в виду, что в большинстве случаев у вас должно быть достаточно места на вашем компьютере, чтобы прочитать весь файл в память. Листинг 8 использует комбинацию оператора/| with и метода
read () . В этом случае мы будем использовать
read() для загрузки содержимого файла в виде потока данных.
# define the name of the file to read from filename = "test.txt" with open(filename, 'r') as filehandle: filecontent = filehandle.read() print (filecontent)
Листинг 8
Python также предлагает метод readlines ()
, который аналогичен методу readline()
из первого примера. В отличие от read()
, содержимое файла хранится в виде списка, где каждая строка содержимого является элементом. Листинг 9 показывает, как получить доступ к этим данным:
# define the name of the file to read from filename = "test.txt" with open(filename, 'r') as filehandle: filecontent = filehandle.readlines() for line in filecontent: print (line)
Листинг 9
В то время как readlines()
будет считывать содержимое из файла до тех пор, пока оно не достигнет EOF, имейте в виду, что вы также можете ограничить объем считываемого содержимого, предоставив параметр sizehint
, который является количеством байтов для чтения.
Вывод
Как обычно, существует несколько способов чтения содержимого файла. С точки зрения скорости все они более или менее относятся к одной категории. Что касается того, какое решение лучше всего подходит для вас, то это зависит от вашего конкретного случая использования. Мы считаем, что очень полезно посмотреть, что возможно, а затем выбрать решение, которое подходит лучше всего.
Хотя Python значительно упрощает процесс чтения файлов, иногда он все же может стать сложным, и в этом случае я бы рекомендовал вам ознакомиться с официальной документацией Python для получения дополнительной информации.
Ресурсы
- Как правильно читать файл в Python, https://www.smallsurething.com/how-to-read-a-file-properly-in-python/
- Обработка больших файлов с помощью python, http://www.blopig.com/blog/2016/08/processing-large-files-using-python/
- Модуль Python itertools, https://docs.python.org/3.6/library/itertools.html
- Модуль linecache Python, https://docs.python.org/3.6/library/linecache.html
Признание
Автор хотел бы поблагодарить Золеку Хатитонгве за ее поддержку при подготовке статьи.