Найти в Дзене
programmer's notes (python and more)

ООП на Python. Создание и удаление объектов. Приложение к видео 6

Доброго времени суток, читатели, зрители моего канала programmer's notes.

Приложение к уроку

Создание и удаление объектов. Конструкторы и деструкторы

Очень важный вопрос, связанный с созданием и удалением объекта. Тут важно уяснить себе не только и не столько, как исполнитель Python создаёт и удаляет объекты, а то, как это использовать в прикладном программировании. Можно ещё конкретнее: как отлавливать событие создания и удаления объекта. Почему это важно? Потому, что возможно, каждый раз при создании объекта нужно производить те или иные действия. Например, инициализацию переменных, открытие файлы, передачу данных и т.п. Можно, конечно каждый раз вызывать какой-то метод непосредственно после создания объекта. Но лучше если это будет автоматизировано. Также и при удалении объекта, возможно, следует закрыть канал связи, файл и т.п. Будем называть конструктором метод, который автоматически запускается при создании объекта, а деструктором метод, который автоматически запускается при удалении объекта из памяти. При чём, исходя из определения, количество конструкторов и деструкторов в общем то может быть более одного. Например, один метод запускается перед созданием объекта, а другой после.

Все специальные методы в Python3, а они называются еще магическими, имеют заведомо определённые имена с двумя подчеркиваниями перед и после имени. Для конструктора это __init__. Первым параметром этого метода является объект (переменная, указывающая на объект), поэтому как минимум __init__(self), т.е. один параметр всегда есть. Остальные параметры могут быть при необходимости. Они указываются при создании объекта: m = Myclass(p1, p2) - дополнительно указали еще два параметра.

Ниже представлена программа с конструктором

Текст программы ниже
Текст программы ниже
primer206.py

Результат выполнения программы

100

Как видим, в конструкторе есть дополнительный параметр со значением по умолчанию.

С деструктором всё несколько интересней. Объясню почему. Если объект мы явно создаем, выполняя соответствующую команду, то объект может удаляться явно и не явно.

1. Все объекты удаляются по окончанию работы программы.

2. Объект можно удалить с помощью оператора del.

3. Специальная система сборки удаляет объект, если не осталось ссылок на него, т.е. нет переменных, которые на него указывают.

4. Как следствие пункта 3) объект удаляется при выходе из области видимости.

Метод-деструктор называется __del__.

Ниже представлен пример программы. Деструктор срабатывает, когда количество ссылок на объект становится равным нулю (см. переменные m и g).

Текст программы ниже
Текст программы ниже
primer207.py

Результат выполнения программы

Конструктор
==============
==============
Деструктор
==============

Как видим объект сразу был удалён после выполнения
g = None.

Замечание
Ровно тот же результат мы получим, если будем использовать оператор del. Он не удаляет сам объект, а только ту переменную, которая на объект указывает. Объект удалится, когда будут удалены все переменные, которые указывают на данный объект.

Ниже дан скриншот фрагмента программы, когда объект создается внутри функции. В этом случае, по окончанию работы функции, все созданные объекты удаляются, если только мы не сохранили их посредством глобальных переменных или путём присвоения через return m, например.

Объект автоматически удаляется после выхода из функции
Объект автоматически удаляется после выхода из функции

Отметим важное. Деструктор выполняется до того, как объект будет уничтожен.

Метод __init__() не единственный конструктор. Есть также метод __new__() который выполняется до создания объекта. Собственно, именно в нём должен быть создан объект, который он должен возвратить исполняющей системе Python. Заметим также, что в качестве параметра этот метод получает имя класса.

Рассмотрим программу, представленную ниже.

Текст программы ниже
Текст программы ниже
primer208.py

Результат выполнения программы

Перед созданием объекта
Инициализация
<__main__.Myclass object at 0x7ff513155b50>
100

Конечно всех должна заинтересовать строка

ins = super().__new__(my)

Позволю себе пока не объяснять её до конца. Замечу только

1. Вот как раз здесь создается объект, ссылка на который должна быть возвращена через return.

2. Данная строка является следствием того, что все классы python являются наследниками одного класса object. И это работает по умолчанию. А о наследовании будем говорить на одном из будущих уроков.

3. super() позволяет вызвать специальный метод класса object, который и создаёт объект, указанного класса.

4. Возвращая полученный объект, мы, тем самым обеспечиваем корректный запуск метода __init__(). Кстати, можно возвратить и другой существующий объект и система python попытается запустить __init__() для этого объекта. Хотя смысла в этом никакого не вижу.

Замечу, кстати, что метод __new__() используется довольно редко, а вот __init__() нужно, конечно, брать на вооружение.

Всего наилучшего. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.

Программировать, друзья мои, легко и приятно
Программировать, друзья мои, легко и приятно