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

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

Жанры

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

Еще один способ получить объект некоторого типа — использование функций–фабрик. По синтаксису вызов функции–фабрики не отличается от вызова конструктора класса.

Определение класса

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

Листинг

from sets import Set as set # тип для множества

class G:

def __init__(self, V, E):

self.vertices = set(V)

self.edges = set(E)

def add_vertex(self, v):

self.vertices.add(v)

def add_edge(self, (v1, v2)):

self.vertices.add(v1)

self.vertices.add(v2)

self.edges.add((v1, v2))

def has_edge(self, (v1, v2)):

return (v1, v2) in self.edges

def __str__(self):

return "%s; %s» % (self.vertices, self.edges)

Использовать

класс можно следующим образом:

Листинг

g = G([1, 2, 3, 4], [(1, 2), (2, 3), (2, 4)])

print g

g.add_vertex(5)

g.add_edge((5,6))

print g.has_edge((1,6))

print g

что даст в результате

Листинг

Set([1, 2, 3, 4]); Set([(2, 4), (1, 2), (2, 3)])

False

Set([1, 2, 3, 4, 5, 6]); Set([(2, 4), (1, 2), (5, 6), (2, 3)])

Как видно из предыдущего примера, определить класс не так уж сложно. Конструктор класса имеет специальное имя __init__. (Деструктор здесь не нужен, но он бы имел имя __del__.) Методы класса определяются в пространстве имен класса. В качестве первого формального аргумента метода принято использовать self. Кроме методов в объекте класса имеются два атрибута: vertices (вершины) и edges (ребра). Для представления объекта G в виде строки используется специальный метод __str__.

Принадлежность классу можно выяснить с помощью встроенной функции isinstance:

Листинг

print isinstance(g, G)

Инкапсуляция

Обычно считается, что без инкапсуляции невозможно представить себе ООП, что это ключевое понятие. История развития методологий программирования движима борьбой со сложностью разработки программного обеспечения. Сложность больших программных систем, в создании которых участвует сразу большое количество разработчиков, уменьшается, если на верхнем уровне не видно деталей реализации нижних уровней. Собственно, процедурный подход был первым шагом на этом пути. Под инкапсуляцией (incapsulation, что можно перевести по–разному, но на нужные ассоциации хорошо наводит слово «обволакивание») понимается сокрытие информации о внутреннем устройстве объекта, при котором работа с объектом может вестись только через его общедоступный (public) интерфейс. Таким образом, другие объекты не должны вмешиваться в «дела» объекта, кроме как используя вызовы методов.

В языке Python инкапсуляции не придается принципиального значения: ее соблюдение зависит от дисциплинированности программиста. В других языках программирования имеются определенные градации доступности методов объекта.

Доступ к свойствам

В языке Python не считается зазорным получить доступ к некоторому атрибуту (не методу) напрямую, если, конечно, этот атрибут описан в документации как часть интерфейса класса. Такие атрибуты

называются свойствами (properties). В других языках программирования принято для доступа к свойствам создавать специальные методы (вместо того чтобы напрямую обращаться к общедоступным членам–данным). В Python достаточно использовать ссылку на атрибут, если свойство ни на что в объекте не влияет (то есть другие объекты могут его произвольно менять). Если же свойство менее тривиально и требует каких–то действий в самом объекте, его можно описать как свойство (пример взят из документации к Python):

Листинг

class C(object):

def getx(self): return self.__x

def setx(self, value): self.__x = value

def delx(self): del self.__x

x = property(getx, setx, delx, «I'm the 'x' property.»)

Синтаксически доступ к свойству x будет обычной ссылкой на атрибут:

Листинг

>>> c = C

>>> c.x = 1

>>> print c.x

1

>>> del c.x

А на самом деле будут вызываться соответствующие методы: setx, getx, delx.

Следует отметить, что в экземпляре класса в Python можно организовать доступ к любым (даже несуществующим) атрибутам, обрабатывая запрос на доступ к атрибуту группой специальных методов:

__getattr__(self, name) Этот метод объекта вызывается в том случае, если атрибут не найден другим способом (его нет в данном экземпляре или в дереве классов). Здесь name — имя атрибута. Метод должен вычислить значение атрибута либо возбудить исключение AttributeError. Для получения полного контроля над атрибутами в «новых» классах (то есть потомках object) используйте метод __getattribute__.

__setattr__(self, name, value) Этот метод вызывается при присваивании значения некоторому атрибуту. В отличие от __getattr__, метод всегда вызывается, а не только тогда, когда атрибут может быть найден в экземпляре класса, поэтому нужно с осторожностью присваивать значения атрибутам внутри этого метода: это может вызвать рекурсию. Для присваивания значений атрибутов предпочтительнее присваивать словарю __dict__: self.__dict__[name] = value или (для «новых» классов) - обращение к __setattr__ базового класса: object.__setattr__(self, name, value).

__delattr__(self, name) Как можно догадаться из названия, этот метод служит для удаления атрибута.

Следующий небольшой пример демонстрирует все перечисленные моменты. В этом примере из словаря создается объект, именами атрибутов которого будут ключи словаря, а значениями — значения из словаря по заданным ключам:

Листинг

class AttDict(object):

def __init__(self, dict=None):

object.__setattr__(self, '_selfdict', dict or {})

def __getattr__(self, name):

if self._selfdict.has_key(name):

return self._selfdict[name]

else:

raise AttributeError

def __setattr__(self, name, value):

if name[0] != '_':

self._selfdict[name] = value

else:

raise AttributeError

def __delattr__(self, name):

if name[0] != '_' and self._selfdict.has_key(name):

del self._selfdict[name]

ad = AttDict({'a': 1, 'b': 10, 'c': '123'})

print ad.a, ad.b, ad.c

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

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

INDIGO
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 5

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Низший - Инфериор. Компиляция. Книги 1-19

Михайлов Дем Алексеевич
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
5.00
рейтинг книги
Низший - Инфериор. Компиляция. Книги 1-19

Рассвет русского царства 3

Грехов Тимофей
3. Новая Русь
Фантастика:
историческое фэнтези
альтернативная история
5.00
рейтинг книги
Рассвет русского царства 3

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Я Гордый часть 6

Машуков Тимур
6. Стальные яйца
Фантастика:
фэнтези
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 6

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

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

Анти-Ксенонская Инициатива

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

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

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

Бастард Императора. Том 12

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

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Идеальный мир для Лекаря 18

Сапфир Олег
18. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 18

Законы Рода. Том 7

Андрей Мельник
7. Граф Берестьев
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Законы Рода. Том 7

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12