Что делают __init__ и self в Python?
Проблема с пониманием параметра self
и метода __init__
в Python
Я изучаю язык программирования Python и столкнулся с чем-то, что я не совсем понимаю.
У меня есть метод, который выглядит следующим образом:
def method(self, blah):
def __init__(?):
....
....
Что делает параметр self
? Какова его роль? Является ли он обязательным?
Также, что делает метод __init__
? Почему он необходим? (и т.д.)
Я полагаю, что это может быть связано с концепциями ООП, но я не обладаю достаточными знаниями в этой области.
5 ответ(ов)
В этом коде:
class A(object):
def __init__(self):
self.x = 'Hello'
def method_a(self, foo):
print self.x + ' ' + foo
переменная self
представляет экземпляр самого объекта. В большинстве объектно-ориентированных языков этот параметр передается как скрытый параметр в методы, определенные для объекта; в Python вы должны явно указать его. Когда вы создаете экземпляр класса A
и вызываете его методы, self
будет автоматически передаван, как в следующем коде:
a = A() # Мы не передаем никаких аргументов в метод __init__
a.method_a('Sailor!') # Мы передаем только один аргумент
Метод __init__
в Python можно считать аналогом конструктора. Когда вы вызываете A()
, Python создает объект для вас и передает его в качестве первого параметра в метод __init__
. Любые дополнительные параметры (например, A(24, 'Hello')
) также будут переданы в качестве аргументов — в этом случае это вызовет исключение, поскольку конструктор не ожидает дополнительных аргументов.
Да, вы правы, это конструкции ООП.
__init__
— это конструктор класса. Параметр self
ссылается на экземпляр объекта (аналогично this
в C++).
class Point:
def __init__(self, x, y):
self._x = x
self._y = y
Метод __init__
вызывается после того, как память для объекта выделена:
x = Point(1, 2)
Важно использовать параметр self
внутри метода объекта, если вы хотите сохранить значение вместе с объектом. Если, например, вы реализуете метод __init__
следующим образом:
class Point:
def __init__(self, x, y):
_x = x
_y = y
Ваша переменные x
и y
будут храниться в стековой памяти и будут уничтожены, когда метод init
выйдет из области видимости. Присваивание этих переменных как self._x
и self._y
делает их членами объекта Point
(доступными на протяжении всего времени существования объекта).
Примечание. Некоторая ясность в использовании слова "конструктор" в этом ответе. Технически, обязанности "конструктора" разделены между двумя методами в Python. Эти методы — __new__
(ответственный за выделение памяти) и __init__
(как обсуждалось здесь, ответственный за инициализацию вновь созданного экземпляра).
Краткий пояснительный пример
В надежде, что это поможет немного прояснить вопрос, вот простой пример, который я использовал, чтобы понять разницу между переменной, объявляемой внутри класса, и переменной, объявляемой внутри метода __init__
:
class MyClass(object):
i = 123
def __init__(self):
self.i = 345
a = MyClass()
print(a.i)
print(MyClass.i)
Вывод будет следующим:
345
123
В этом примере i
, которую мы объявили внутри MyClass
, является переменной класса и доступна через сам класс. А self.i
, определяемая в методе __init__
, является атрибутом экземпляра класса и переопределяет значение переменной класса для конкретного объекта. Поэтому вывод показывает, что a.i
возвращает значение 345, присвоенное атрибуту экземпляра, в то время как MyClass.i
возвращает 123, значение переменной класса.
Вкратце:
self
, как и подразумевается, ссылается на самого себя — на объект, который вызвал метод. То есть, если у вас есть N объектов, вызывающих метод, тогдаself.a
будет ссылаться на отдельный экземпляр переменной для каждого из N объектов. Представьте, что существует N копий переменнойa
для каждого объекта.__init__
— это то, что в других языках ООП, таких как C++ или Java, называется конструктором. Основная идея заключается в том, что это специальный метод, который автоматически вызывается при создании объекта данного класса.
Да, __init__
действительно выполняет роль конструктора в Python. Если вы хотите, чтобы методы вашего класса работали как нестатические, вам необходимо передавать "self" в качестве первого аргумента в эти функции. "self" представляет собой экземпляр переменных для вашего класса.
Понимание Python super() с методами __init__()
Почему классы в Python наследуют от object?
Разница между старыми и новыми классами в Python?
Как использовать десятичное значение шага в range()?
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе