Объекты и классы в Python
Python — объектно-ориентированный язык программирования. В отличие от процедурно-ориентированного программирования, ООП опирается на объекты.
Объект — это набор данных (переменных) и методов (функций), которые с этими данными взаимодействуют.
Представьте чертеж дома. В нем содержится вся информация: сколько этажей, какого размера двери, окна и т. д. На основе это чертежа мы можем построить дом. Дом — это объект.
По одному чертежу можно построить сразу несколько домов. Так же и с классом — по нему можно создать много объектов. Объект также можно назвать экземпляром класса, а процесс его создания — инстанцированием.
Как объявить класс
По аналогии с функциями, которые начинаются с def , объявление класса сопровождается ключевым словом class .
Первая строка внутри класса называется строкой документации, в ней содержится краткое описание класса. Писать ее рекомендуется, но не обязательно.
class MyNewClass: '''Это строка документации. Мы создали новый класс''' pass
Класс создает новое локальное пространство имен, где определяются все атрибуты. Атрибутами могут быть и переменные, и функции.
Есть и специальные атрибуты, которые начинаются с двойного нижнего подчеркивания __ . Например, __doc__ — строка документации класса.
После объявления класса создается объект этого класса с тем же именем. Этот объект класса позволяет нам как получить доступ к различным его атрибутам, так и инстанцировать новые объекты этого класса.
class Person: "Это класс, описывающий человека" age = 10 def greet(self): print('Привет') # Вывод: 10 print(Person.age) # Вывод: print(Person.greet) # Вывод: 'Это мой второй класс' print(Person.__doc__)
10
Это класс, описывающий человека
Как создать объект
Мы уже знаем, что объект класса можно использовать для доступа к различным его атрибутам.
Использовать его можно и для создания новых экземпляров этого класса. Создание объекта похоже на вызов функции.
Так мы создадим новый экземпляр класса — harry . Доступ к атрибутам объекта осуществляется при помощи префикса имени объекта.
Атрибутами могут быть и переменные, и методы. Методы объекта — функции этого класса.
Это значит следующее: Person.greet — объект функции (атрибут класса), а harry.greet — объект метода.
class Person: "Это класс, описывающий человека" age = 10 def greet(self): print('Привет') # создаем новый объект класса Person harry = Person() # Вывод: print(Person.greet) # Вывод: > print(harry.greet) # Вызов метода greet() объекта # Вывод: Привет harry.greet()
Возможно, вы заметили параметр self в функции класса. Но вызывали метод мы с помощью harry.greet() . И почему-то это сработало.
Так происходит потому, что когда объект вызывает свой метод, сам объект является первым аргументом. То есть harry.greet() это то же самое, что и Person.greet(harry) .
Обычно вызов метода со списком аргументов длины n равносилен вызову соответствующей функции со списком аргументов, который создается путем вставки объекта метода перед первым аргументов.
По этим причинам первый аргумент функции в классе должен быть сам объект. Это и есть self — так договорились программисты на Python. Но в теории можно использовать и другое обозначение.
Теперь вы имеете представление о классах, экземплярах класса, функциях, методах. Главное — понимать их отличия.
Конструкторы
Функции класса, начинающиеся с двойного нижнего подчеркивания, называются специальными функциями.
Наибольший интерес вызывает специальная функция __init__( ). Она вызывается каждый раз, когда вы создаете новый объект класса.
В ООП этот вид функций называют конструкторами. Обычно они используются для инициализации всех переменных класса.
class ComplexNumber: def __init__(self, r=0, i=0): self.real = r self.imag = i def get_data(self): print(f'+j') # Создаем новый объект ComplexNumber num1 = ComplexNumber(2, 3) # Вызываем метод get_data() # Вывод: 2+3j num1.get_data() # Создаем еще один объект ComplexNumber # и новый атрибут 'attr' num2 = ComplexNumber(5) num2.attr = 10 # Вывод: (5, 0, 10) print((num2.real, num2.imag, num2.attr)) # У объекта c1 нет атрибута 'attr', поэтому # вызывается ошибка # AttributeError: 'ComplexNumber' object has no attribute 'attr' print(num1.attr)
2+3j
(5, 0, 10)
Traceback (most recent call last):
File "", line 27, in
print(num1.attr)
AttributeError: 'ComplexNumber' object has no attribute 'attr'
В этом примере мы объявили класс, представляющий комплексные числа. В нем две функции. Первая, __init__() , инициализирует переменные (по умолчанию это нули). Вторая, get_data() , позволяет правильно отображать числа в консоли.
Стоит отметить, что атрибуты объекта могут создаваться «на лету». Мы и создали, и считали атрибут attr объекта num2 . Но это не значит, что этот атрибут будет доступен num1 .
Как удалить атрибуты и объекты
Любой атрибут объекта можно в любой момент удалить. Сделать это можно с помощью оператора del . Попробуйте запустить следующую программу и проверьте, что она выводит.
>>> num1 = ComplexNumber(2,3) >>> del num1.imag >>> num1.get_data()
Traceback (most recent call last):
.
AttributeError: 'ComplexNumber' object has no attribute 'imag'
>>> del ComplexNumber.get_data >>> num1.get_data()
Traceback (most recent call last):
.
AttributeError: 'ComplexNumber' object has no attribute 'get_data'
С помощью del можно удалить даже объект:
>>> c1 = ComplexNumber(1,3) >>> del c1 >>> c1
Traceback (most recent call last):
.
NameError: name 'c1' is not defined
На самом деле всё намного сложнее. Когда мы выполняем строку c1 = ComplexNumber(1,3) , создается новый экземпляр класса. Переменная с1 является ссылкой на него.
После выполнения команды del c1 ссылка и имя c1 удаляются из соответствующего пространства имен. Однако объект все так же будет существовать. Так что если не связать новую переменную с этим объектом, он позже будет автоматически уничтожен.
Удаление объектов, на которые нет ссылок, называется сборкой мусора.
Python class
Основы
Python — это мультипарадигменный язык программирования. Это означает, что в Питоне есть инструменты как процедурной (функциональной) парадигмы, так и объектно-ориентированной (ООП). Классы относятся к объектно-ориентированному стилю программирования. Именно о них мы поговорим в этом уроке.
Процедурно-ориентированный стиль
Процедурно-ориентированная парадигма – это такой подход к программированию, когда код строится на основе функций в математическом смысле этого слова.
Объектно-ориентированный стиль
ООП в Python 3 подразумевает построение кода, оперирующего такими понятиями как python классы и объекты, при этом сама программа создается как некоторая совокупность объектов, которые взаимодействую друг с другом. Объектно-ориентированное программирование ещё долгое время будет являться передовой, если даже не основной, парадигмой программирования. Прямая связь ООП с реальным миром позволяет глубже понимать устройство и принципы работы, как самого языка, так и написания кода в целом, а так же облегчает проектирование внутренней архитектуры.
В данной парадигме есть ряд принципов, которые необходимо знать и понимать.
Абстракция
Абстракция — это модель, в которой уделено внимание основным характеристикам, а остальные опущены. Это упрощение, которое помогает нашему восприятию, один из способов бороться со сложностью.
Инкапсуляция
Согласно этому принципу вся реализация скрывается внутри абстракции, а внешние пользователи взаимодействуют только с интерфейсом. Это даёт разработчику свободу менять различные детали реализации, не боясь, что у кого-то из пользователей что-то сломается. С другой стороны, всё, что входит в интерфейс (публичные атрибуты) должно быть сохранено в неприкосновенности – каждый пользователь должен быть уверен, что интерфейс не изменится со временем.
Наследование
Наследование – возможность создать новый класс, базирующийся на уже созданном другом классе. В таком случае класс–потомок получает все методы и атрибуты от класса-родителя. Далее, как правило, классу-потомку добавляют новые детали.
Полиморфизм
Полиморфизм – это подход, в котором у класса-наследника можно перегрузить методы и атрибуты класса-родителя. При этом можно оперировать всеми потомками класса, точно зная, что они имеют его атрибуты, пусть и видоизменённые.
Создание класса в Python
Классы создаются следующим образом: