Выбор класса Python

vybor klassa python Базы данных и постоянное хранение

Когда Python восстанавливает экземпляр класса, извлеченный из хранилища, он воссоздает в памяти объект экземпляра, повторно импортируя класс, используя сохраненные строки с именами класса и модуля; присваивает сохраненный словарь атрибутов новому пустому экземпляру класса и связывает экземпляр с классом. Эти действия выполняются по умолчанию, но имеется возможность изменить этот процесс, определив специальные методы, которые будут вызываться модулем pickle при извлечении и сохранении информации об экземпляре (за подробностями обращайтесь к руководству по библиотеке Python).

Главное здесь то, что класс и хранимые экземпляры отделены друг от друга. Сам класс не хранится вместе со своими экземплярами, а находится в исходном файле модуля Python и импортируется заново, когда загружаются экземпляры.

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

Для иллюстрации предположим, что класс Person из предыдущего раздела был изменен, как показано в примере 17.3.

Пример 17.3. PP4E\Dbase\person.py (вер сия 2)

объект с информацией о сотруднике: поля + поведение изменения: метод tax теперь является вычисляемым атрибутом

class Person:

def __init__(self, name, job, pay=0): self.name = name self.job = job

self.pay = pay # действительные данные экземпляра

def __getattr__(self, attr): # в person.attr

if attr == tax‘:

return self.pay * 0.30 # вычисляется при попытке обращения else:

raise AttributeError() # другие неизвестные атрибуты

def info(self):

return self.name, self.job, self.pay, self.tax

В этой версии устанавливается новая ставка налога (30%), вводится метод __getattr__ перегрузки операции доступа к атрибуту класса и убран оригинальный метод tax. Поскольку при загрузке экземпляров из хранилища будет импортирована эта новая версия класса, они автоматически приобретут новую реализацию поведения — попытки обращения к атрибуту tax будут перехватываться и в ответ будет возвращаться вычисленное значение:

C:\\PP4E\Dbase> python

>  >> import shelve

>  >> dbase = shelve.open(‘cast’) # открыть хранилище

>>> 

>  >> print(list(dbase.keys())) # в хранилище присутствуют оба объекта [‘bob‘, ‘emily‘]

>>> print(dbase[’emily’])

<person.Person object at 0x019AEE90>

>>> 

>  >> print(dbase[‘bob‘].tax) # больше не требуется вызывать tax()

21000.0

Так как класс изменился, к атрибуту tax теперь можно обращаться как к простому свойству, не вызывая его как метод. Кроме того, поскольку ставка налога в классе изменена, Бобу придется на этот раз платить больше. Конечно, этот пример искусственный, но при правильном использовании такое разделение классов и постоянно хранимых экземпляров может избавить от необходимости использовать традиционные программы обновления баз данных — чтобы добиться нового поведения, в большинстве случаев можно просто изменить класс, а не каждый хранящийся экземпляр.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий