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

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

Жанры

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

Листинг

class Tree:

# …

def convert(cls, val):

if isinstance(val, Tree):

children = [cls.convert(child) for child in val]

return cls(val.node, children)

else:

return val

convert = classmethod(convert)

Пример использования (взят из строки документации метода convert):

Листинг

>>> # Преобразовать tree в экземпляр класса Tree

>>> tree = Tree.convert(tree)

>>> # " " " " " ParentedTree

>>> tree = ParentedTree.convert(tree)

>>> # " " " " " MultiParentedTree

>>> tree = MultiParentedTree.convert(tree)

Метод

класса позволяет более естественно описывать действия, которые связаны в основном с классами, а не с методами экземпляра класса.

Метаклассы

Еще одним отношением между классами является отношение класс–метакласс. Метакласс можно считать «высшим пилотажем» объектно–ориентированного программирования, но, к счастью, в Python можно создавать собственные метаклассы.

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

Пример, в котором класс порождается динамически в функции–фабрике классов:

Листинг

def cls_factory_f(func):

class X(object):

pass

setattr(X, func.__name__, func)

return X

Использование будет выглядеть так:

Листинг

def my_method(self):

print «self:", self

My_Class = cls_factory_f(my_method)

my_object = My_Class

my_object.my_method

В этом примере функция cls_factory_f возвращает класс с единственным методом, в качестве которого используется функция, переданная ей как аргумент. От этого класса можно получить экземпляры, а затем у экземпляров — вызвать метод my_method.

Теперь можно задаться целью построить класс, экземплярами которого будут классы. Такой класс, от которого порождаются классы, и называется метаклассом.

В Python имеется класс type, который на деле является метаклассом. Вот как с помощью его конструктора можно создать класс:

Листинг

def my_method(self):

print «self:", self

My_Class = type('My_Class', (object,), {'my_method': my_method})

В качестве первого параметра type передается имя класса, второй параметр — базовые классы для данного класса, третий — атрибуты.

В результате получится класс, эквивалентный следующему:

Листинг

class My_Class(object):

def my_method(self):

print «self:", self

Но самое интересное начинается при попытке составить собственный метакласс. Проще всего наследовать метакласс от метакласса type (пример взят из статьи

Дэвида Мертца):

Листинг

>>> class My_Type(type):

… def __new__(cls, name, bases, dict):

… print «Выделение памяти под класс», name

… return type.__new__(cls, name, bases, dict)

… def __init__(cls, name, bases, dict):

… print «Инициализация класса», name

… return super(My_Type, cls).__init__(cls, name, bases, dict)

>>> my = My_Type(«X», , {})

Выделение памяти под класс X

Инициализация класса X

В этом примере не происходит вмешательство в создание класса. Но в __new__ и __init__ имеется полный программный контроль над создаваемым классом в период выполнения.

Примечание:

Следует заметить, что в метаклассах принято называть первый аргумент методов не self, а cls, чтобы напомнить, что экземпляр, над которым работает программист, является не просто объектом, а классом.

Мультиметоды

Некоторые объектно–ориентированные «штучки» не входят в стандартный Python или стандартную библиотеку. Ниже будут рассмотрены мультиметоды — методы, сочетающие объекты сразу нескольких различных классов. Например, сложение двух чисел различных типов фактически требует использования мультиметода. Если «одиночный» метод достаточно задать для каждого класса, то мультиметод требует задания для каждого сочетания классов, которые он обслуживает:

Листинг

>>> import operator

>>> operator.add(1, 2)

3

>>> operator.add(1.0, 2)

3.0

>>> operator.add(1, 2.0)

3.0

>>> operator.add(1, 1+2j)

(2+2j)

>>> operator.add(1+2j, 1)

(2+2j)

В этом примере operator.add ведет себя как мультиметод, выполняя разные действия для различных комбинаций параметров.

Для организации собственных мультиметодов можно воспользоваться модулем Multimethod (автор Neel Krishnaswami), который легко найти в Интернете. Следующий пример, адаптированный из документации модуля, показывает построение собственного мультиметода:

Листинг

from Multimethod import Method, Generic, AmbiguousMethodError

# классы, для которых будет определен мультиметод

class A: pass

class B(A): pass

# функции мультиметода

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))

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

Спасите меня, Кацураги-сан! Том 2

Аржанов Алексей
2. Токийский лекарь
Фантастика:
городское фэнтези
попаданцы
дорама
фэнтези
5.00
рейтинг книги
Спасите меня, Кацураги-сан! Том 2

Лихие. Смотрящий

Вязовский Алексей
2. Бригадир
Фантастика:
попаданцы
5.00
рейтинг книги
Лихие. Смотрящий

Попаданка. Финал

Ахминеева Нина
4. Двойная звезда
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Попаданка. Финал

Санек 2

Седой Василий
2. Санек
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Санек 2

Имя нам Легион. Том 11

Дорничев Дмитрий
11. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 11

На границе империй. Том 10. Часть 7

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 7

Бастард Императора

Орлов Андрей Юрьевич
1. Бастард Императора
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Бастард Императора

Я все еще не князь. Книга XV

Дрейк Сириус
15. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще не князь. Книга XV

Жнец

Поселягин Владимир Геннадьевич
1. Жнец
Фантастика:
попаданцы
альтернативная история
6.40
рейтинг книги
Жнец

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Хозяин Стужи

Петров Максим Николаевич
1. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
7.00
рейтинг книги
Хозяин Стужи

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

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

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