Экспресс-курс по Python: Лекция №5 Работа с файлами

Настоящее программирование невозможно без обработки файлов. В языке Python есть различные средства для работы с текстовыми и бинарными файлами. Разница между этими файлами условная, которая состоит в том, что при обработке текстовых файлов работают со строками, которые разделяются с помощью специальных символов.

Сначала рассмотрим классический способ работы с файлами. Для работы с файлами первым делом необходимо его открыть и получить переменную, с помощью которой можно будет работать. Для этого используем функцию open. Эта функция напоминает соответствующую функцию в языке C. Первым параметром необходимо указать имя файла, а втором режим открытия этого файла в виде строки. Наиболее частые режимы открытия:

r - открытие на чтение.

w - открытие на запись. Если файл с указанным именем существует, он будет перезаписан. Если такого файла нет, то он будет создан.

a - открытие на запись. Если файл с указанным именем существует, он будет открыт, указатель будет установлен в конец файла, содержимое файла не изменится. Если такого файла нет, то он будет создан.

Если в к этим символам добавить "b", то это будет означать, что файл должен быть открыт как бинарный.

После открытия файла его нужно закрыть командой методом close(). Вот простой пример:

f = open("mama.txt", "w")
f.write("Мама мыла раму.\n")
f.write("Конец")
f.close()
В результате будет создан файл с именем mama.txt, который будет содержать текст:

Мама мыла раму.
Конец

Заметим, что нам необходимо самим следить за тем, чтобы записываемая строка имела в конце символ конца строки, иначе записываемые строки будут слипаться в одну.

Записывать можно и числа:

import math
pi = math.pi
f = open("a.txt", "w")
f.write(pi.__str__())
f.close()

В результате в файл a.txt будет записана строка

3.141592653589793

Для чтения файла можно использовать метод readline(), который считывает одну строку из файла. Но для этого необходимо открыть файл на запись. Вот пример

f = open("a.txt", "r")
pi = float(f.readline())
pi = pi * 2
print(pi)
f.close()

Если файл был создан нашей предыдущей программой, то в результате на экране будет выведено

6.283185307179586

Заметим, что при чтении строки мы ее преобразуем в числовой формат с помощью функции float(), потому что в противном случае мы бы получили не удвоенное число pi, а двукратное повторение строки.

Очень часто при работе с файлами возникает задача последовательного чтения всех строк файла. В Python это делается с помощью цикла for s in f, где f открытый на чтение файл, а s строка, читаемая из файла. Приведем пример программы, которая сначала создает текстовый файл из чисел от 1 до 10, а потом его читает и выводит квадраты чисел.

f = open("a.txt", "w")
for n in range(10):
    f.write((n + 1).__str__() + "\n")
f.close()
 
f = open("a.txt", "r")
for s in f:
    x = int(s)
    x = x * x
    print(x)
f.close()

1
4
9
16
25
36
49
64
81
100

Кстати, с помощью метода readlines() можно считать все строки файла в список, а с помощью метода writelines список строк можно записать в текстовый файл.

Рассмотрим еще работу с бинарными файлами. Напишем программу, которая запрашивает у пользователя число, потом записывает в файл их квадрат, куб и четвертую степень. При этом мы хотим, чтобы в файле хранились не в текстовом виде, а в двоичном формате. При этом использование методов write() является не самым удачным решением. Более правильный подход состоит в использовании механизма сериализации объектов. Сериализация объекта состоит в том, что все поля класса записываются в файл в двоичном формате, а потом в нужный момент могут быть восстановлены. Поскольку в Python каждая переменная является классом, то сериализацию можно использовать и для каждой переменной.

Средства для работы с сериализацией реализованы в модуле pickle, поэтому в начале программы нужно будет подключить командой

import pickle

Далее, если у нас есть открытый двоичный файл на запись в переменной f и некоторая переменная A, то для того, чтобы записать ее в файл с помощью сериализации необходимо выполнить следующую команду

pickle._dump(A, f)

Чтобы потом восстановить значение этой переменной из двоичного файла f, который должен быть открыт на чтение, нужно выполнить команду

A = pickle._load(f)

Приведем теперь полный текст программы

import pickle
 
a = int(input("Введите число > "))
 
f = open("a.bin", "wb")
b = a * a
pickle._dump(b, f)
b = a * a * a
pickle._dump(b, f)
b = a * a * a * a
pickle._dump(b, f)
f.close()
 
f = open("a.bin", "rb")
b = pickle._load(f)
print(b.__str__())
b = pickle._load(f)
print(b.__str__())
b = pickle._load(f)
print(b.__str__())
f.close()

Заметим, что с помощью сериализации можно записывать в файл не только отдельные переменные, но и целые списки классов. Рассмотрим модельный пример, в котором мы создадим класс для отображения некоторой персоны, а потом создадим список, состоящий из экземпяров этого класса. Сохраним этот список в файле:

import pickle
 
class TPers:
    name = ""
    date = 0
    def __init__(self, name, date):
        self.name = name
        self.date = date
 
    def type(self):
        print("Person: " + self.name + "; Date = " + self.date.__str__())
 
Pers = []
Pers.append(TPers("Shamin Roman", 1975))
Pers.append(TPers("Kuznetsov Konstantin", 1981))
 
for p in Pers:
    p.type()
 
f = open("pers.dat", "wb")
pickle._dump(Pers, f)
f.close()

Person: Shamin Roman; Date = 1975
Person: Kuznetsov Konstantin; Date = 1981

Теперь напишем программу, в которой мы восстановим значения наших классов с помощью средств сериализации.

import pickle
 
class TPers:
    name = ""
    date = 0
    def __init__(self, name, date):
        self.name = name
        self.date = date
 
    def type(self):
        print("Person: " + self.name + "; Date = " + self.date.__str__())
 
f = open("pers.dat", "rb")
Pers = pickle._load(f)
f.close()
 
for p in Pers:
    p.type()

Person: Shamin Roman; Date = 1975
Person: Kuznetsov Konstantin; Date = 1981

Таким образом, мы видим, что работа с файлами в Python довольно простая и эффективная.

Home | Лекции | Python | Видео | Скачать | Ссылки
Copyright (c) 2017, Roman Shamin
147
43527
77