Курс по Python ООП: https://stepik.org/a/116336
На этом занятии мы поговорим о
начальной инициализации объектов в момент их создания и финализации при их
удалении.
В каждом классе
языка Python есть набор
предопределенных «магических» методов. Да, это такое общепринятое название.
Магические методы начинаются и заканчиваются двумя подчеркиваниями:
__ имя метода__
В частности
существуют два таких метода:
-
__init__(self)
– инициализатор объекта класса
-
__del__(self)
– финализатор класса
Первый вызывается
сразу после создания экземпляра класса, а второй – перед непосредственным его
удалением. Давайте посмотрим, как они работают и зачем нужны.
Я вернусь к
примеру из прошлого занятия, где мы с вами определили класс с двумя свойствами color и circle и двумя
методами set_coords и get_coords:
class Point:
color = 'red'
circle = 2
def set_coords(self, x, y):
self.x = x
self.y = y
def get_coords(self):
return (self.x, self.y)
Использовать на
практике такой класс не очень удобно, так как после создания объекта:
координат x, y в нем никаких
не будет. Дополнительно для этого нужно еще вызывать метод:
Было бы хорошо
сделать эти действия сразу в момент создания экземпляра класса. И поможет нам в
этом магический метод __init__. Давайте сначала мы его пропишем в
самом простом виде:
class Point:
color = 'red'
circle = 2
def __init__(self):
print("вызов __init__")
self.x = 0
self.y = 0
...
Здесь первый
параметр self является ссылкой
на созданный экземпляр класса, через который мы создаем в этом новом объекте
локальные свойства x, y. В результате, создавая экземпляр класса:
мы увидим в
консоли, что, во-первых, произошел вызов этого метода и, во-вторых, в объекте pt были созданы
два локальных свойства x, y с нулевыми
значениями:
Детально это
работает, следующим образом. Вначале происходит создание объекта в памяти
устройства. Непосредственно перед его созданием вызывается магический метод __new__ (О нем мы еще
будем говорить). Затем, после успешного создания объекта, вызывается магический
метод __init__ для начальной
инициализации созданного объекта. В результате, у нас появляются два локальных
атрибута x и y.
Давайте теперь
сделаем так, чтобы в момент создания экземпляра класса мы могли сразу указывать
значения координат точки. Для этого в инициализаторе можно прописывать дополнительные
параметры:
def __init__(self, a, b):
self.x = a
self.y = b
И при создании
объекта с таким инициализатором мы уже должны в круглых скобках передавать эти
два аргумента:
Если этого не
сделать, то возникнет ошибка и объект создан не будет.
Обратите
внимание, я специально в качестве дополнительных параметров указал имена a и b. При этом, в
самом объекте создаются локальные свойства с именами x и y. То есть, то,
что мы прописываем после self, то и является именем нового атрибута.
Конечно, на практике, обычно, имена параметров в инициализаторе совпадают с
именами создаваемых свойств и лучше записать инициализатор в таком виде:
def __init__(self, x, y):
self.x = x
self.y = y
Также всегда
следует помнить, что метод __init__ - это обычная функция, поэтому мы в
качестве дополнительных параметров можем указывать и фактические и формальные
параметры. Например, так:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
Тогда, при
создании объектов мы можем вообще не указывать аргументы:
Либо указать
один или два:
pt = Point(10)
pt = Point(10, 20)
То есть, здесь
все ровно так, как и с обычными функциями.
Финализатор объекта класса
Я, надеюсь, вы
теперь хорошо себе представляете, как работает инициализатор объектов класса и
зачем он нужен. Второй аналогичный магический метод __del__ автоматически
вызывается непосредственно перед уничтожением экземпляра класса. Он называется финализатор.
Давайте пропишем такой магический метод в
классе Point, следующим
образом:
def __del__(self):
print("Удаление экземпляра: "+ str(self))
Здесь
по-прежнему self – это ссылка на
экземпляр класса, который будет удален.
После запуска
программы видим, что объект в конце программы действительно был удален и вызван
метод __del__. Но, здесь у
вас может возникнуть вопрос: а когда и в какой момент вообще происходит
удаление объектов. Мы же в программе это явно нигде не указываем? Работает все
достаточно просто. Интерпретатор языка Python имеет, так
называемый, сборщик мусора. Это алгоритм, который отслеживает объекты и
как только они становятся ненужными, удаляет их. Но как он определяет нужный
объект или ненужный? Все очень просто. Пока на какой-либо объект ведет хотя бы
одна внешняя ссылка, то он считается используемым и сохраняется в памяти. Как
только все внешние ссылки пропадают, то сборщик мусора его уничтожает
(освобождает память, которую он занимал).
Итак, из этого
занятия вы должны знать, что такое магический метод и как работают
инициализатор объекта и его финализатор. А также в какой момент и когда они
вызываются. Если все это понятно, то жду всех вас на следующем занятии.
Курс по Python ООП: https://stepik.org/a/116336