Лекція 13

advertisement
Лекція 13. Поняття "серіалізація" в програмуванні.
Поняття "серіалізація" в програмуванні: модуль pickle. Розробка простих баз даних на
основі використання списків, словників, набору класів та модулю pickle. Загальні
принципи побудови інформаційно - довідкових систем. Поняття про таблиці прецедентів,
модель предметної області та діаграми послідовності.
В большинстве языков программирования сохранение структурированных данных в
файлах (потоках) представляет некоторые трудности. Это связано с тем, что эти типы
данных, как правило, являются не встроенными типами данных, а "надстройками" над
системой. В Питоне этот вопрос решается довольно просто, т.к. большинство
распространенных сложных типов данных являются "встроенными" типами, а такие типы,
как классы, являются надстройками над базовыми типами.
Следующие модули обеспечивают сохранение структурированных данных в файлах.
pickle Преобразует объекты языка Python в последовательность байтов и обратно.
cPickle
shelve
Более быстрый вариант модуля pickle.
Сохранение объектов в базе данных в стиле DBM.
marshal Позволяет получить байт-компилированное представление объектов кода (и
сопутствующих им объектов) и восстановить объекты из их байт компилированного представления.
struct
Преобразование объектов в структуры языка C.
pickle и cPickle - представление объектов в виде последовательности байтов.
Модуль pickle реализует простой, но мощный алгоритм "консервирования" ( pickling,
преобразования объектов в последовательность байтов) почти любых объектов язы ка
Python с возможностью дальнейшего восстановления ( unpickling). Однако этот модуль не
заботится о сохранении имен объектов и не обеспечивает к ним совместный доступ.
Полученную последовательность байтов Вы можете записать в файле, сохранить в базе
данных или переслать по сети на другую машину. Модуль shelve предоставляет простой интерфейс для сохранения "законсервированных" объектов в базе данных в стиле
DBM.
В то время как реализованный на языке Python модуль pickle работает достаточно
медленно, реализованный на C модуль cPickle работает иногда почти в 1000 раз
быстрее. Модуль cPickle использует точно такой же алгоритм и имеет анало гичный
интерфейс, за исключением того, что вместо классов Pickler и Unpickler
используются функции, возвращающие объекты с аналогичным интерфейсом.
Хотя модули pickle и cPickle и используют внутри себя встроенный модуль
marshal, они отличаются от этого модуля способом обработки данных:
• Модули pickle и cPickle отслеживают объекты, которые уже были обрабо таны,
и никогда не обрабатывают их повторно. Это позволяет "консервировать"
рекурсивные объекты (объекты, содержащие ссылки на себя), которые не могут
быть обработаны модулем marshal. Аналогично обрабатываются совместно ис пользуемые объекты (различные объекты ссылаются на оди н и тот же объект): они
остаются совместно используемыми, что очень важно для изменяемых объек тов.
• Модуль marshal совсем не поддерживает экземпляры классов, в то время как мо дули pickle и cPickle позволяют с ними работать. Определение класса должно
находиться в том же модуле, в котором оно было при "консервации" объекта.
Используемый формат данных характерен для языка Python и не имеет ограничений, характерных, например, для стандартного формата XDR (External Data
Representation), который не позволяет представить совместное использование объектов.
Однако это означает, что программы на других языках не смогут восстановить
"законсервированный" объект.
По умолчанию для представления используются только печатные ASCII символы,
что позволяет просматривать файл с данными с помощью обычного текстового редакто ра
с целью отладки или восстановления данных. С другой стороны, такое представление
занимает больше места, чем двоичный формат. Вы можете выбрать двоичный формат, ис пользуя ненулевое значение аргумента bin конструктора Pickler и функций dump() и
dumps() .
Модули pickle и cPickle не поддерживают объекты кода. В этом нет большой
необходимости, так как для "консервирования" объектов кода традиционно используется
модуль marshal. Кроме того, это позволяет избежать возможного включения в файлы
данных троянских коней.
на объекты, которые не подлежат "консервированию". Для таких объ ектов
запоминается идентификатор, возвращаемый атрибутом -функцией или методом
persistent_id(). Идентификатор может быть произвольной строкой из печатных
ASCII символов. Для восстановления объекта по идентификатору необходимо опреде лить
атрибут-функцию persistent_load() .
На "консервирование" экземпляров классов есть несколько ограничений. Во первых, класс должен быть определен в глобальном пространстве имен одного из
модулей. Во-вторых, все переменные экземпляра (то есть атрибут __dict__ ) должны поддерживать "консервацию" или же экземпляр класса должен иметь метод
_getstate ___ () протокола копирования, возвращающий объект, который поддер живает "консервацию".
При восстановлении экземпляра класса его метод
init () обычно не вызывается. Для того, чтобы он вызывался, класс должен иметь метод __getinitargs__()
протокола копирования. Другие методы протокола копирования (см. раздел ?? )
__getstate__() и __setstate__() используются для сохранения и восстановле ния состояния объекта.
Обратите внимание, что при "консервации" экземпляра класса сам объект -класс
и, соответственно, его атрибуты не сохраняются — сохраняются только атрибуты экземпляра и запоминается имя класса и модуля, в котором класс определен. Поэтому
класс должен быть определен в глобальном пространстве имен модуля, который, од нако, в момент восстановления может быть и не импортирован. Это сделано с целью
иметь возможность исправить ошибки в определении класса или добавить новые методы
и загрузить объект, созданный со старой версией класса. Если Вы собираетесь работать
с долгоживущими объектами, которые переживут множество версий класса, разумно
сохранить номер версии класса, чтобы затем необходимые преобразования могли быть
выполнены методом ___ setstate __ ().
Модули pickle и cPickle определяют следующие конструкторы
Pickler (file [, bin])
Класс (в модуле pickle) или функция (в модуле cPickle), возвращает объект,
реализующий "консервирование". Аргумент file должен быть файловым объектом, имеющим метод write(). Если задан отличный от нуля аргумент bin (целое
число), используется более компактный двоичный формат.
Unpickler( file)
Класс (в модуле pickle) или функция (в модуле cPickle), возвращает объект,
реализующий восстановление "законсервированного" объекта. Аргумент file должен быть файловым объектом, имеющим методы read() и readline() .
Объекты, возвращаемые конструктором Pickler() , имеют следующие (основные)
методы:
dump (object)
"Консервирует" объект object.
persistent_id(object)
Этот метод (функция или любой другой объект, поддерживающий вызов) вызывает ся для каждого из вложенных объектов. Должен возвращать строку -идентификатор
постоянного объекта или None, если объект подлежит консервации. Изначально
метод persistent_id() не определен (cPickle) или всегда возвращает None
(pickle).
Объекты, возвращаемые конструктором Unpickler() , имеют методы, предназначенные для выполнения обратных действий:
load ()
Восстанавливает и возвращает ранее "законсервированный" объект
noload() (только в модуле cPickle)
Проходит весь цикл восстановления объекта, но сам объект не создает. Может быть
полезен для тестирования persistent_load
persistent_load(id_string)
Этот метод (функция или любой другой объект, поддерживающий вызов)
вызывается для восстановления ссылки на постоянный объект по строке идентификатору id_string, которая при "консервации" была возвращена мето дом persistent_id(). Изначально метод persistent_load() не определен.
Вы можете несколько раз вызывать метод dump() объекта Pickler. Для восстановления всех "законсервированных" объектов необходимо будет столько же раз
вызвать метод load() соответствующего объекта Unpickler(). Если один и тот же
объект "консервируется" несколько раз методом dump() одного и того же объекта
Pickler, метод load() восстановит ссылки на один и тот же объект. Предполагается,
что "консервация" нескольких объектов производится без внесения в них изменений в
промежутке между вызовами метода load() . Если Вы измените объект и затем повторно "законсервируете" его с помощью того же объекта Pickler, объект не будет
"законсервирован" — сохранится лишь ссылка на старое значение.
Кроме конструкторов Pickler() и Unpickler(), модули определяют следующие
функции и объекты данных:
dump (objectf file [, bin])
"Консервирует" объект object в файл file. Эквивалентно вызову 'Pickler(
file, bin).dump(object) ' .
load( file)
Восстанавливает "законсервированный" объект из файла file и возвращает его.
dumps (object [, bin])
Возвращает "законсервированное" представление объекта в виде строки вместо
того, чтобы записывать его в файл.
loads( string)
Восстанавливает "законсервированный" объект из строки string и возвращает
его.
format_version
Строка-версия формата, используемого при "консервации".
compatible_formats
Список старых версий (строк) формата данных, которые, помимо текущей версии
(format_version), могут быть восстановлены.
Ниже приведена иерархия исключений, которые используются модулями pickle и
cPickle при возникновении ошибок (до версии 2.0 исключения определены в виде
строк, что сильно затрудняет их обработку):
PickleError
Базовый класс для всех исключений, является производным от стандартного класса
исключений Exception.
PicklingError
Класс исключений, которые генерируются при попытке "законсервировать"
объект, который не может быть "законсервирован".
UnpicklingError
Класс исключений, которые генерируются при восстановлении объекта, если
его конструктор не зарегистрирован (см. описание модуля copy_reg).
Ниже приведен список объектов, которые могут быть "законсервированы":
• None;
• Целые, длинные целые и вещественные числа.
• Простые строки и строки Unicode.
Кортежи, списки и словари, содержащие только объекты, которые могут быть "за консервированы".
• Классы и функции, определенные в глобальном пространств имен модуля (на самом
деле запоминаются только имена модуля и функции).
• Экземпляры классов, атрибут ___ dict __ которых может быть "законсервирован".
• Экземпляры классов, имеющих соответствующие методы протокола копирован ия
(см. раздел ?? ).
• Объекты, поддержка которых зарегистрирована с помощью модуля copy_reg.
Именно таким образом осуществляется поддержка комплексных чисел.
marshal — байт-компилированное представление объектов
dump (object, file)
Записывает байт-компилированное представление объекта object в файл. Аргумент file должен быть объектом типа file, открытым для записи в двоичном
режиме ('wb' или 'w+b'). Если для объекта object не может быть получено
байт-компилированное представление, генерируется исключен ие ValueError, но
при этом в файл будет записан "мусор", который не будет корректно считан
функцией load() .
load( file)
Считывает байт-компилированное представление для одного объекта из файла, вос станавливает его и возвращает. Если данные в файле не мог ут быть корректно обработаны, в зависимости от ситуации генерируется одно из исключений EOFError,
ValueError или TypeError. Аргумент file должен быть объектом типа file,
открытым для чтения в двоичном режиме ( rb
или r+b ).
dumps( object)
Возвращает строку с байт-компилированным представлением объекта object.
loads(string)
Восстанавливает объект из байт-компилированного представления string. Лишние
символы в строке игнорируются.
Download