Объектно-ориентированное программирование. Общее представление
Объектно-ориентированное программирование (ООП) — парадигма программирования, в которой основными концепциями являются понятия объектов и классов. Класс — тип, описывающий устройство объектов. Объект — это экземпляр класса. Класс можно сравнить с чертежом, по которому создаются объекты. Python соответствует принципам объектно-ориентированного программирования. В python всё является объектами - и строки, и списки, и словари, и всё остальное. Но возможности ООП в python этим не ограничены. Программист может написать свой тип данных (класс), определить в нём свои методы. Это не является обязательным - мы можем пользоваться только встроенными объектами. Однако ООП полезно при долгосрочной разработке программы несколькими людьми, так как упрощает понимание кода. Приступим теперь собственно к написанию своих классов на python. Попробуем определить собственный класс: # Пример самого простейшего классаclass A: passТеперь мы можем создать несколько экземпляров этого класса: >>> a = A()>>> b = A()>>> a.arg = 1 # у экземпляра a появился атрибут arg, равный 1>>> b.arg = 2 # а у экземпляра b - атрибут arg, равный 2>>> print(a.arg)1Классу возможно задать собственные методы: class A: def g(self): # self - обязательный аргумент, содержащий в себе экземпляр класса, передающийся при вызове метода, # поэтому этот аргумент должен присутствовать во всех методах класса. return 'hello world' >>> a = A()>>> a.g()'hello world'И еще один пример: class B: arg = 'Python' # Все экземпляры этого класса будут иметь атрибут arg, равный "Python" # Но впоследствии мы его можем изменить def g(self): return self.arg >>> b = B()>>> b.g()'Python'>>> B.g(b)'Python' >>> b.arg = 'spam'>>> b.g()'spam'
Инкапсуляция, наследование, полиморфизм Недавно мы говорили об основах объектно-ориентированного программирования в python, теперь продолжим эту тему и поговорим о таких понятиях ООП, как инкапсуляция, наследование иполиморфизм. Инкапсуляция Инкапсуляция — ограничение доступа к составляющим объект компонентам (методам и переменным). Инкапсуляция делает некоторые из компонент доступными только внутри класса. Инкапсуляция в Python работает лишь на уровне соглашения между программистами о том, какие атрибуты являются общедоступными, а какие — внутренними. Одиночное подчеркивание в начале имени атрибута говорит о том, что переменная или метод не предназначен для использования вне методов класса, однако атрибут доступен по этому имени. class A: def _private(self): print("Это приватный метод!") >>> a = A()>>> a._private()Это приватный метод! Двойное подчеркивание в начале имени атрибута даёт большую защиту: атрибут становится недоступным по этому имени. class B: def __private(self): print("Это приватный метод!") >>> b = B()>>> b.__private()Traceback (most recent call last): File "", line 1, in b.__private()AttributeError: 'B' object has no attribute '__private'Однако полностью это не защищает, так как атрибут всё равно остаётся доступным под именем _ИмяКласса__ИмяАтрибута: >>> b._B__private()Это приватный метод!Наследование Наследование подразумевает то, что дочерний класс содержит все атрибуты родительского класса, при этом некоторые из них могут быть переопределены или добавлены в дочернем. Например, мы можем создать свой класс, похожий на словарь: class Mydict(dict): def get(self, key, default = 0): return dict.get(self, key, default) a = dict(a=1, b=2)b = Mydict(a=1, b=2)Класс Mydict ведёт себя точно так же, как и словарь, за исключением того, что метод get по умолчанию возвращает не None, а 0. >>> b['c'] = 4>>> print(b){'a': 1, 'c': 4, 'b': 2}>>> print(a.get('v'))None>>> print(b.get('v'))0Полиморфизм Полиморфизм - разное поведение одного и того же метода в разных классах. Например, мы можем сложить два числа, и можем сложить две строки. При этом получим разный результат, так как числа и строки являются разными классами. >>> 1 + 12>>> "1" + "1"'11'
Перегрузка операторов Перегрузка операторов — один из способов реализации полиморфизма, когда мы можем задать свою реализацию какого-либо метода в своём классе. Например, у нас есть два класса: class A: def go(self): print('Go, A!') class B(A): def go(self, name): print('Go, {}!'.format(name))В данном примере класс B наследует класс A, но переопределяет метод go, поэтому он имеет мало общего с аналогичным методом класса A. Однако в python имеются методы, которые, как правило, не вызываются напрямую, а вызываются встроенными функциями или операторами. Например, метод __init__ перегружает конструктор класса. Конструктор - создание экземпляра класса. class A: def __init__(self, name): self.name = name >>> a = A('Vasya')>>> print(a.name)VasyaСобственно, далее пойдёт список таких "магических" методов. __new__(cls[, ...]) — управляет созданием экземпляра. В качестве обязательного аргумента принимает класс (не путать с экземпляром). Должен возвращать экземпляр класса для его последующей его передачи методу __init__. __init__(self[, ...]) - как уже было сказано выше, конструктор. __del__(self) - вызывается при удалении объекта сборщиком мусора. __repr__(self) - вызывается встроенной функцией repr; возвращает "сырые" данные, использующиеся для внутреннего представления в python. __str__(self) - вызывается функциями str, print и format. Возвращает строковое представление объекта. __bytes__(self) - вызывается функцией bytes при преобразовании к байтам. __format__(self, format_spec) - используется функцией format (а также методом format у строк). __lt__(self, other) - x < y вызывает x.__lt__(y). __le__(self, other) - x ≤ y вызывает x.__le__(y). __eq__(self, other) - x == y вызывает x.__eq__(y). __ne__(self, other) - x != y вызывает x.__ne__(y) __gt__(self, other) - x > y вызывает x.__gt__(y). __ge__(self, other) - x ≥ y вызывает x.__ge__(y). __hash__(self) - получение хэш-суммы объекта, например, для добавления в словарь. __bool__(self) - вызывается при проверке истинности. Если этот метод не определён, вызывается метод __len__ (объекты, имеющие ненулевую длину, считаются истинными). __getattr__(self, name) - вызывается, когда атрибут экземпляра класса не найден в обычных местах (например, у экземпляра нет метода с таким названием). __setattr__(self, name, value) - назначение атрибута. __delattr__(self, name) - удаление атрибута (del obj.name). __call__(self[, args...]) - вызов экземпляра класса как функции. __len__(self) - длина объекта. __getitem__(self, key) - доступ по индексу (или ключу). __setitem__(self, key, value) - назначение элемента по индексу. __delitem__(self, key) - удаление элемента по индексу. __iter__(self) - возвращает итератор для контейнера. __reversed__(self) - итератор из элементов, следующих в обратном порядке. __contains__(self, item) - проверка на принадлежность элемента контейнеру (item in self).
Популярное: Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ... Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней... Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (761)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |