Саммерфилд - Программирование на Python 3 (1077331), страница 69
Текст из файла (страница 69)
На языке Ру!)топ под консервированием понимается способ сериализации (преобразования в последовательность байтов или в строку) объектов. В консервировании особенно ценно то, что имеется возможность консервировать коллекции, такие как списки или словари, и даже объекты, внутри которых имеются другие объекты (включая коллекции, которые в свою очередь могут включать другие коллекции, и т. д.) — весь объем данных будет законсервирован, причем без дублирования повторяющихся объектов. Законсервированный объект можно прочитать прямо в пере- т! менную РуФ)топ — нам не потребуется выполнять тот или иной <' '>> вид парсинга.
То есть консервирование объектов идеально подходит для сохранения и загрузки специализированных коллекций данных, особенно в маленьких программах и в программах, разрабатываемых для личного пользования. Однако Глава б. Объектно-ориентированное программирование при консервировании не используются механизмы обеспечения безопасности (данные не шифруются и электронная подпись не добавляется), поэтому загрузка законсервированных объектов из непроверенных источников может быть опасным делом. Ввиду этого в программах, предназначенных не только для личного пользования, лучше выработать собственный формат файлов, — специфичный для программы.
В главе 7 будет показано, как читать и писать файлы с двоичными данными, с текстом и с данными в формате ХМЬ. бет ване(ве11, т!1епаве=носе): тт 111епаае !в пот Иоле: ветт.т!1епаае = Г!1епаае тт пот ве1т.тт1епаее: га1ве ИоР11епааеЕггог() ГП = Иове тгу: бата = [ве1т.упбтп, ве1т.пе!Опт. ве11. оаскогоопб, ве[т, бата] ГП = орел(веы т!1епаае, тве") ртсК1е.боер(бата, ТП, р!сК!е.Н16НЕЕТ РЯОТОСО[) ехсерт (епу!гопаептеггог, р1ск1е.Ртск1тпреггог) ав егг: га!ве БачеЕггог(втг(егг)) !!па!1у тг тп тв пот Иоле: тп.с!ове() Первая часть функции просто проверяет наличие имени файла. Если объект [варе был создан без указания имени файла и после этого имя файла не было установлено, то при вызове метода вауе() необходимо явно указывать имя файла (в этом случае он выполняет операцию всохранить каке и устанавливает значение атрибута [11епаве). Если имя файла не было указано при вызове метода, то используется текущее значение атрибута Т!1епаие, а если текущее имя файла не задано, то возбуждается исключение.
Затем создается список, в который добавляются данные объекта для сохранения, включая словарь ве1(. бата с элементами координаты- цвет, но исключая множество уникальных цветов, поскольку этн данные легко реконструируются. Далее открывается файл для записи в двоичном режиме и вызывается функция р!сК1е.боер(), которая записывает данные объекта в файл.
Вот и все! Модуль р1сК1е может сериализовать данные с использованием разных форматов (в документации они называются лротоколамк). Формат определяется третьим аргументом функции р1сК1е. боер(). Протокол О— это АЯСП, его удобно использовать во время отладки. Мы использовали протокол 3 (ртсК1е.
Н1ОНЕЯТ РНОТОСО[) — компактный двоичный формат, именно поэтому файл был открыт в режиме записи двоичных данных. При чтении файлов с законсервированными объектами протокол Собственные классы коллекций не указывается — функция р!сК1е. 1оаб() автоматически определяет ис- пользуемый протокол.
бес 1оаб(ае1(, Г!)епаае=воле); ст гс1епаае !а пос Воле; ае1т.с!1епаае = Гс!епаве !т пос ае1а.тс1епаве: гасае ИЬЕс1епавеЕггог() Гп = Иопе сгу: гь = ареп(ае1с.тс1епаве, "гь") баса = рсск1е. 1Ьаб(гь) (ае1(. и!бш, ае1с па!рос, ае1(. ьаскргоопб, ае1(. баса) = бата ае1г. со1ога = (аес(ае1(. баса.уа1оеа()) (ае1(. ЬасКргоопб)) ехсерс (епусгопаепсеггаг, р!ск1а.ьпр!ск1!преггог) аа егг: гасае еоабеггог(асг(егг)) Г!па11у: ст СЬ са поС Иоле: ГЬ с1оае() Эта функция, так же как и функция аауе(), начинается с определения имени файла, который требуется загрузить.
Файл должен быть открыт для чтения в двоичном режиме, а сама операция чтения выполняется единственной инструкцией бата = рссК1е,!оаб(тп). Объект бата — это точная реконструкция сохранявшегося объекта. То есть в данном случае это список, содержащий целочисленные значения ширины и высоты, строку с цветом фона и словарь с элементами координаты-цвет. Для присваивания каждого элемента списка баса соответствующей переменной выполняется операция распаковывания кортежа, поэтому любые имевшиеся данные, хранившиеся в объекте 1ааде, будут (корректно) потеряны. Множество уникальных цветов реконструируется посредством создания множества всех цветов, хранящихся в словаре, после чего в множество добавляется цвет фона.
бег ехрогс(ае1(, т!1епаае): !т г!1епаае. 1оаегО .епбаассп(".хрв"); ве1г. ехрогс хра(гс1епаае) е1ае. гале ЕхрогСЕггог("опаоррогтеб ехрогт Гогват. оа, раса, ар1!секс( г!1епаае)( 1)) Мы реализовали один универсальный метод экспорта, где по расширению файла определяется имя вызываемого метода или возбуждается исключение, если запрошенный формат экспорта не поддерживается. В данном случае поддерживается экспорт только в файлы .хрлс (и только для изображений, насчитывающих не более 8 930 цветов).
Мы не приводим реализацию метода ехрогС хрв(), потому что он никак не 314 Глава 6. Объектно-ориентированное программирование связан с темой главы, но в исходных текстах примеров к этой книге он, конечно же, присутствует. На этом мы завершаем рассмотрение класса 1ваде. Этот класс является типичным представителем типов данных, используемых для хранения специфических данных в программах, обеспечивая возможность доступа к элементам содержащихся в нем данных, возможность сохранения на диск и загрузки с диска своих данных и предоставляя только необходимые методы.
В следующих двух подразделах мы увидим, как создать два типа коллекций, обладающие полным АР1. Создание классов коллекций посредством агрегирования В этом подразделе мы создадим полный тип коллекции Бог1еадтв1, который представляет собой список, хранящий свои элементы в порядке сортировки.
Сортировка выполняется с помощью оператора «меньше чем» (<), действие которого реализуется специальным методом 11 (), или с помощью функции, которая передается в виде аргумента Кеу. Класс стремится соответствовать АР1 встроенного класса 11вт, чтобы максимально упростить его освоение, но некоторые методы не могут быть реализованы по вполне объяснимым причинам, например, использование оператора конкатенации (+) может привести к нарушению порядка сортировки элементов, поэтому мы не реализуем его. Как всегда, когда создается свой собственный класс, у нас есть выбор— наследовать класс, подобный тому, что создается, или создать новый класс с нуля, агрегируя в него экземпляры других, необходимых классов.
Для класса Богтег)11вт, рассматриваемого в этом подразделе, мы будем использовать подход на основе агрегирования элементов данных, а в следующем подразделе, где рассматривается создание класса Богтео01ст, мы будем использовать не только агрегирование, но и наследование. В главе 8 мы узнаем, что классы могут брать на себя обязательства поддерживать определенные типы АР1, Например, класс 1(вт поддерживает АР1 Мзтао)еБесзепсе, то есть поддерживает оператор тп, встроенные функции (тег() и 1еп(), оператор доступа к элементам ((]) для получения, установки и удаления элементов, а также метод (пзегт().
Класс Богтеодтвт, представленный здесь, не поддерживает возможность изменения значений элементов и не имеет метода 1пвегт(), поэтому он не поддерживает АР1 Матао1еБедоепсе. Если бы мы создавали класс Бог1ео(.твт, наследуя класс 11вт, окончательная реализация заявляла бы о себе как об изменяемой последовательности, но не имела бы полного АР1.
Поэтому класс Богтебд1вт не наследует класс 1тзт и не делает никаких утверждений о своем АР1. С другой стороны, класс Богтеод1ст, рассматриваемый в следующем подразделе, реализует полный АР1 Мв1аа1еМарр(пд, который поддерживается классом отст, поэтому мы смогли создать его как подкласс класса о1ст. Собственные классы коллекций Ниже приводятся несколько типичных примеров использования клас- са Яогтерр [вт: 1емегв = Всгтесс!вт.Всгтесствт(("н", "с", "В".
"Г, "е"), втг. 1снег) в втг(1еттегв) == "['В', 'с', 'е', '6', 'н']" 1еыегв.асс("О") !еттегв.асс("т") 1еттегв.асс("А") в вггиеыегв) == "['и', 'В', 'с', 'е', 'т', 'В', 'В', 'н']" 1еттегв[2] Ф вернет: 'с' Объект класса Вогтеоб(в! представляет собой агрегат [композицию) из двух частных атрибутов — функции ве1!. Кеу() (ссылка на объект ве1т. Неу) и списка ве1т. 1!Вт. Ключевая функция передается во втором аргумен е (или в виде именованного аргумента Кеу, если начальная по- фупхцхх следовательность не задана).
Если ключевая функция стр.215 задана, используется частная функция модуля: 1еепттту = 1авспа х: х Это функция тождественности: она просто возвращает свой аргумент, не изменяя его, поэтому, когда она используется в качестве ключевой функции, это означает, что ключом сортировки объектов в списке являются сами объекты. Тип Зогтео[1в! не поддерживает возможность изменения элементов с помощью оператора доступа к элементам ([]) (и поэтому не реализует специальный метод ве!1теэ ()), а также не имеет методов эррера() или ехтепо(), поскольку они могут нарушать порядок сортировки. Единственный способ добавить элементы в сортированный список состоит в том, чтобы передать последовательность при создании объекта Вогтесс1вт, или добавлять их позднее, с помощью метода Яогтег)- Ств!.
ВОО(). С другой стороны, мы безопасно можем использовать оператор доступа к элементам для получения значения или удаления элемента в указанной позиции, потому что ни одна из этих операций не оказывает влияния на порядок сортировки, поэтому были реализованы обаспециальныхметода Вес)сев () и Ве1ттев (). Теперь мы перейдем к последовательному рассмотрению методов класса и, как обычно, начнем с инструкции с1авв и метода инициализации: с1авв ЯсгтеССтвт: се! тп11 (ве11, вециепсе=лопе, кеу=нспе); ве1(.