Чтение онлайн

на главную - закладки

Жанры

Язык программирования Python
Шрифт:

g.add_method(Method((B, A), m3))

# применение мультиметода

try:

print 'Типы аргументов:', 'Результат'

print 'A, A:', g(A, A)

print 'A, B:', g(A, B)

print 'B, A:', g(B, A)

print 'B, B:', g(B, B)

except AmbiguousMethodError:

print 'Неоднозначный выбор метода'

Устойчивые объекты

Для того чтобы объекты жили дольше, чем создавшая их программа, необходим механизм их представления в виде последовательности байтов. Во второй лекции уже рассматривался модуль pickle, который

позволяет сериализовать объекты.

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

__getinitargs__ Должен возвращать кортеж из аргументов, который будет передаваться на вход метода __init__ при создании объекта.

__getstate__ Должен возвращать словарь, в котором выражено состояние объекта. Если этот метод в классе определен, то используется атрибут __dict__, который есть у каждого объекта.

__setstate__(state) Должен восстанавливать объекту ранее сохраненное состояние state.

В следующем примере класс CC управляет своим копированием (точно так же экземпляры этого класса смогут консервироваться и расконсервироваться при помощи модуля pickle):

Листинг

from time import time, gmtime

import copy

class CC:

def __init__(self, created=time):

self.created = created

self.created_gmtime = gmtime(created)

self._copied = 1

print id(self), «init», created

def __getinitargs__(self):

print id(self), «getinitargs», self.created

return (self.created,)

def __getstate__(self):

print id(self), «getstate», self.created

return {'_copied': self._copied}

def __setstate__(self, dict):

print id(self), «setstate», dict

self._copied = dict['_copied'] + 1

def __repr__(self):

return "%s obj: %s %s %s» % (id(self), self._copied,

self.created, self.created_gmtime)

a = CC

print a

b = copy.deepcopy(a)

print b

В результате будет получено

Листинг

1075715052 init 1102751640.91

1075715052 obj: 1 1102751640.91 (2004, 12, 11, 7, 54, 0, 5, 346, 0)

1075715052 getinitargs 1102751640.91

1075729452 init 1102751640.91

1075715052 getstate 1102751640.91

1075729452 setstate {'copied': 1}

1075729452 obj: 2 1102751640.91 (2004, 12, 11, 7, 54, 0, 5, 346, 0)

Состояние объекта состоит из трех атрибутов: created, created_gmtime, copied. Первый из этих атрибутов может быть восстановлен передачей параметра конструктору. Второй — вычислен в конструкторе на основе первого. А вот третий не входит в интерфейс класса и может быть передан только через механизм getstate/setstate. Причем, по смыслу этого атрибута при каждом копировании он должен увеличиваться на единицу (хотя в разных случаях атрибут может требовать других действий или не требовать их вообще).

Следует включить отладочные операторы вывода, чтобы отследить последовательность вызовов методов при копировании.

Механизм getstate/setstate позволяет передавать при копировании только то, что нужно для воссоздания объекта, тогда как атрибут __dict__ может содержать много лишнего. Более того, __dict__ может содержать объекты, которые просто так сериализации не поддаются, и поэтому getstate/setstate — единственная возможность обойти подобные ограничения.

Примечание:

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

Для хранения объектов используются не только простейшие механизмы хранения вроде pickle.dump/pickle.load или полки shelve. Сериализованные объекты Python можно хранить в специализированных хранилищах объектов (например, ZODB) или реляционных базах данных.

Это также касается передачи объектов по сетям передачи данных. Если простейшие объекты (вроде строк или чисел) можно передавать напрямую через HTTP, XML–RPC, SOAP и т.д., где они имеют собственный тип, то произвольные объекты необходимо консервировать на передающей стороне и расконсервировать на принимающей.

Критика ООП

Объектно–ориентированный подход сегодня считается «самым передовым». Однако не следует слепо верить в его всемогущество. Отдача (в виде скорости разработки) от объектного проектирования чувствуется только в больших проектах и в проектах, которые родственны объектному подходу: построение графического интерфейса, моделирование систем и т.п.

Также спорна большая гибкость объектных программ к изменениям. Она зависит от того, вносится ли новый метод (для серии объектов) или новый тип объекта. При процедурном подходе при появлении нового метода пишется отдельная процедура, в которой в каждой ветке алгоритма обрабатывается свой тип данных (то есть такое изменение требует редактирования одного места в коде). При ООП изменять придется каждый класс, внося в него новый метод (то есть изменения в нескольких местах). Зато ООП выигрывает при внесении нового типа данных: ведь изменения происходят только в одном месте, где описываются все методы для данного типа. При процедурном подходе приходится изменять несколько процедур. Сказанное иллюстрируется ниже. Пусть имеются классы A, B, C и методы a, b, c:

Листинг

# ООП

class A:

def a: …

def b: …

def c: …

class B:

def a: …

def b: …

def c: …

class C:

def a: …

def b: …

def c: …

# процедурный подход

def a(x):

if type(x) is A: …

if type(x) is B: …

if type(x) is C: …

def b(x):

if type(x) is A: …

if type(x) is B: …

if type(x) is C: …

Поделиться:
Популярные книги

Отморозок 5

Поповский Андрей Владимирович
5. Отморозок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Отморозок 5

Барон ломает правила

Ренгач Евгений
11. Закон сильного
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Барон ломает правила

Я все еще барон

Дрейк Сириус
4. Дорогой барон!
Фантастика:
боевая фантастика
5.00
рейтинг книги
Я все еще барон

Локки 10. Потомок бога

Решетов Евгений Валерьевич
10. Локки
Фантастика:
фэнтези
юмористическое фэнтези
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Локки 10. Потомок бога

Вечный. Книга VII

Рокотов Алексей
7. Вечный
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Вечный. Книга VII

Точка Бифуркации IV

Смит Дейлор
4. ТБ
Фантастика:
героическая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации IV

Тринадцатый IX

NikL
9. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Тринадцатый IX

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Путешественник по Изнанке

Билик Дмитрий Александрович
4. Бедовый
Фантастика:
юмористическое фэнтези
городское фэнтези
попаданцы
мистика
5.00
рейтинг книги
Путешественник по Изнанке

Сильнейший Столп Империи. Книга 3

Ермоленков Алексей
3. Сильнейший Столп Империи
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 3

Вернувшийся: Посол. Том IV

Vector
4. Вернувшийся
Фантастика:
космическая фантастика
киберпанк
5.00
рейтинг книги
Вернувшийся: Посол. Том IV

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III

Архил...? 4

Кожевников Павел
4. Архил...?
Фантастика:
фэнтези
попаданцы
альтернативная история
5.50
рейтинг книги
Архил...? 4

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI