9

Что делают __init__ и self в Python?

10

Проблема с пониманием параметра self и метода __init__ в Python

Я изучаю язык программирования Python и столкнулся с чем-то, что я не совсем понимаю.

У меня есть метод, который выглядит следующим образом:

def method(self, blah):
    def __init__(?):
        ....
    ....

Что делает параметр self? Какова его роль? Является ли он обязательным?

Также, что делает метод __init__? Почему он необходим? (и т.д.)

Я полагаю, что это может быть связано с концепциями ООП, но я не обладаю достаточными знаниями в этой области.

5 ответ(ов)

7

В этом коде:

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')) также будут переданы в качестве аргументов — в этом случае это вызовет исключение, поскольку конструктор не ожидает дополнительных аргументов.

3

Да, вы правы, это конструкции ООП.

__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__ (как обсуждалось здесь, ответственный за инициализацию вновь созданного экземпляра).

2

Краткий пояснительный пример

В надежде, что это поможет немного прояснить вопрос, вот простой пример, который я использовал, чтобы понять разницу между переменной, объявляемой внутри класса, и переменной, объявляемой внутри метода __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, значение переменной класса.

0

Вкратце:

  1. self, как и подразумевается, ссылается на самого себя — на объект, который вызвал метод. То есть, если у вас есть N объектов, вызывающих метод, тогда self.a будет ссылаться на отдельный экземпляр переменной для каждого из N объектов. Представьте, что существует N копий переменной a для каждого объекта.

  2. __init__ — это то, что в других языках ООП, таких как C++ или Java, называется конструктором. Основная идея заключается в том, что это специальный метод, который автоматически вызывается при создании объекта данного класса.

0

Да, __init__ действительно выполняет роль конструктора в Python. Если вы хотите, чтобы методы вашего класса работали как нестатические, вам необходимо передавать "self" в качестве первого аргумента в эти функции. "self" представляет собой экземпляр переменных для вашего класса.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь