- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Язык программирования Python - Роман Сузи
Шрифт:
Интервал:
Закладка:
def m1(a, b): return 'AA'
def m2(a, b): return 'AB'
def m3(a, b): return 'BA'
# определение мультиметода (без одной функции)
g = Generic()
g.add_method(Method((A, A), m1))
g.add_method(Method((A, B), m2))
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: ...
def c(x):
if type(x) is A: ...
if type(x) is B: ...
if type(x) is C: ...
При внесении нового типа объекта изменения в ОО–программе затрагивают только один модуль, а в процедурной — все процедуры:
# ООП
class D:
def a(): ...
def b(): ...
def c(): ...
# процедурный подход
def a(x):
if type(x) is A: ...
if type(x) is B: ...
if type(x) is C: ...
if type(x) is D: ...
def b(x):
if type(x) is A: ...
if type(x) is B: ...
if type(x) is C: ...
if type(x) is D: ...
def c(x):
if type(x) is A: ...
if type(x) is B: ...
if type(x) is C: ...
if type(x) is D: ...
И наоборот, теперь нужно добавить новый метод обработки. При процедурном подходе просто пишется новая процедура, а вот для объектного приходится изменять все классы:
# процедурный подход
def d(x):
if type(x) is A: ...
if type(x) is B: ...
if type(x) is C: ...
# ООП
class A:
def a(): ...
def b(): ...
def c(): ...
def d(): ...
class B:
def a(): ...
def b(): ...
def c(): ...
def d(): ...
class C:
def a(): ...
def b(): ...
def c(): ...
def d(): ...
Язык программирования Python изначально был ориентирован на практические нужды. Приведенное выше выражается в стандартной библиотеке Python, то есть в том, что там применяются и функции (обычно сильно обобщенные на довольно широкий круг входных данных), и классы (когда операции достаточно специфичны). Обобщенная природа функций Python и полиморфизм, не завязанный целиком на наследовании — вот свойства языка Python, позволяющие иметь большую гибкость в комбинации процедурного и объектно–ориентированного подходов.
Заключение
Даже достаточно неформальное введение в ООП потребовало определения большого количества терминов. В лекции была сделана попытка с помощью примеров передать не столько букву, сколько дух терминологии ООП. Были рассмотрены все базовые понятия: объект, тип, класс и виды отношений между объектами (IS–A, HAS–A, USE–A). Слушатели получили представление о том, что такое инкапсуляция и полиморфизм в стиле ООП, а также наследование — продление времени жизни объекта за рамками исполняющейся программы, известное как устойчивость объекта (object persistence). Были указаны недостатки ООП, но при этом весь предыдущий материал объективно свидетельствовал о достоинствах этого подхода.