Рубрики
Без рубрики

Чтение файлов с помощью Python

Автор оригинала: 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 для получения дополнительной информации.

Ресурсы

Признание

Автор хотел бы поблагодарить Золеку Хатитонгве за ее поддержку при подготовке статьи.