Что такое “self” в Python?

В языке Python “self” обозначает сам объект класса. С его помощью можно получить доступ к атрибутам и методам класса.

Зеленый круг с надписью Class. Из него выходит и в него же возвращается синяя стрелка, подписанная как self.

Например, класс Fruit при создании присваивает себе пользовательские имя и цвет (name и color). Затем к ним можно будет получить доступ с помощью метода info():

class Fruit:
    def __init__(self, name, color):
        self.name = name
        self.color = color
    
    def info(self):
        print(self.color, self.name)
    
banana = Fruit("Banana", "Yellow")
banana.info()

# Вывод:
# Yellow Banana

Чтобы понять, как это работает, давайте подробнее разберемся с “self” в Python. Это руководство предназначено для тех, кто уже знаком с классами, но кому понятие “self” кажется несколько туманным.

Ключевое слово “self” в Python

В Python класс – это схема для создания объектов.

Каждый объект Python является представителем некоторого класса. В Python объект также называется экземпляром класса. Если вы хотите создать объект в Python, у вас должен быть класс, на основе которого вы можете его создать.

Типичный класс Python состоит из методов, которые выполняют действия на основе атрибутов, присвоенных объекту.

Например, класс Weight может хранить килограммы и иметь возможность конвертировать их в фунты.

В классе Python параметр self ссылается на сам экземпляр класса. Это полезно, поскольку в противном случае не было бы возможности получить доступ к атрибутам и методам класса.

Пример: класс Fruit

Чтобы лучше понять роль “self” в классе, давайте рассмотрим простой класс Fruit. Он позволяет создавать объекты Fruit с пользовательскими именем и цветом (name и color):

class Fruit:
    def __init__(self, name, color):
        self.name = name
        self.color = color
    
    def info(self):
        print(self.color, self.name)

Теперь вы можете создавать объекты Fruit. Делается это так:

banana = Fruit("Banana", "Yellow")
apple = Fruit("Apple", "Red")

И вы можете вывести информацию, связанную с ними:

banana.info()
apple.info()

Вывод:

Yellow Banana
Red Apple

Как работает “self” в этом примере?

Рассмотрим, как работает класс Fruit.

При создании нового объекта Fruit под капотом вызывается метод __init__. Он отвечает за создание объектов. Этот метод принимает три аргумента:

  1. self
  2. name
  3. color

При создании объекта Fruit метод __init__ вызывается с пользовательскими именем и цветом. Обратите внимание, что вам не нужно передавать self в качестве аргумента. Python делает это автоматически.

Таким образом, при вызове banana = Fruit("Banana", "Red"):

  • Метод __init__ начинает инициализацию объекта Banana с заданными аргументами name и color.
  • Он создает новые атрибуты self.name и self.color и сохраняет в них введенные данные name и color.
  • После этого можно получить доступ к атрибутам Banana name и color в любом месте объекта через self.name и self.color.

Посмотрим также, что произойдет при вызове banana.info().

Когда вы вызываете banana.info(), Python автоматически передает self в вызов метода в качестве аргумента. После этого метод info() может использовать self для доступа к атрибутам объекта name и color. Без self он не смог бы этого сделать.

В Python “self” может содержать что угодно

Зеленый круг Class. Внутрь круга, к слову self, ведут стрелки извне, от слов name, age, height, weight, sayHi(), showInfo(), add().

Ранее вы видели, как параметр self может использоваться для хранения атрибутов объектов.

Точнее, вы увидели типичный подход, когда вы передаете __init__ аргументы метода и присваиваете их self с помощью того же имени:

def __init__(self, name, color):
    self.name = name
    self.color = color

В связи с этим может возникнуть вопрос: “Должны ли имена аргументов совпадать с теми, что присваиваются self?”. Ответ – нет.

Подобно тому, как в Python можно создать любую переменную в любом месте, через self вы можете присвоить объекту любые атрибуты.

Это означает, что вы можете хранить в self любые значения с любыми именами. Их даже не обязательно передавать в качестве аргументов в метод __init__.

Пример: класс Point

Например, создадим класс Point, представляющий точку в трехмерном пространстве. Давайте инициализируем объекты Point в начале координат, не запрашивая координаты в качестве аргументов при инициализации.

Для этого необходимо присвоить xy и z значения 0 для self в методе __init__:

class Point:
    def __init__(self):
        self.x = 0
        self.y = 0
        self.z = 0

Теперь можно создавать объекты Point, привязанные к началу координат:

p = Point()
print(p.x, p.y, p.z)

# Вывод:
# 0 0 0 

Этим мы хотим продемонстрировать, как можно свободно добавлять любые атрибуты к свойству объекта self.

Может ли метод не иметь аргумента “self”?

В Python метод нуждается в аргументе self. В противном случае он не знает, к какому классу принадлежит, и не может выполнять над ним действия.

Чтобы посмотреть, что произойдет, если метод не будет принимать аргумент self , давайте пропустим его в методе info() :

class Fruit:
    def __init__(self, name, color):
        self.name = name
        self.color = color
    
    def info():
        print(self.color, self.name)
banana = Fruit("Banana", "Yellow")
banana.info()

Вывод:

Traceback (most recent call last):
  File "main.py", line 10, in <module>
    banana.info()
TypeError: info() takes 0 positional arguments but 1 was given

Последняя строка говорит о том, что метод info() не принимает аргументов, а мы передали один. Но, судя по приведенному выше коду, мы не передавали никаких аргументов. Так почему же интерпретатор думает, что мы это сделали?

Даже если вы не передаете методу info() никаких аргументов,  Python автоматически пытается внедрить self в вызов. Это происходит потому, что Python знает, что для корректной работы все методы класса должны иметь ссылку на сам класс. Но в нашей реализации info() нет аргумента self. Поэтому передача в нее аргумента self за кулисами не удастся.

Это показывает, что в методах необходимо использовать аргумент self.

Доказательство того, что “self” относится к самому объекту

Для наглядности докажем, что self действительно относится к самому объекту.

Для этого проверим расположение в памяти self и объекта Fruit.

В языке Python адрес объекта в памяти можно проверить с помощью функции id(). Класс Fruit упрощен для облегчения восприятия.

class Fruit:
    def __init__(self):
        print("Self address =", id(self))
 
fruit = Fruit()
print("Object address =", id(fruit))

Вывод:

Self address = 140243905604576
Object address = 140243905604576

Как видно, адреса памяти одинаковы. Это говорит о том, что self внутри класса Fruit указывает на тот же адрес, что и объект fruit, который вы только что создали. Другими словами, параметр self действительно ссылается на сам объект.

Ключевое слово “self” не является зарезервированным в Python

Обратите внимание, что self не является зарезервированным ключевым словом в Python. Вместо него можно использовать любое имя, лишь бы оно было.

Зеленый круг, подписанный Class. Из него выходит и в него же возвращается синяя стрелка с рядом подписей на выбор: self, this, me, myself, whatever.

Например, изменим реализацию класса Fruit из предыдущих разделов. На этот раз вместо имени self будем использовать this:

class Fruit:
    def __init__(this, name, color):
        this.name = name
        this.color = color
    
    def info(this):
        print(this.color, this.name)
banana = Fruit("Banana", "Yellow")
apple = Fruit("Apple", "Red")

Этот код работает точно так же, как и тот, в котором используется self.

Но поскольку Python-разработчики чаще всего используют self, не рекомендуется использовать другие слова. При работе с классами в Python вы вряд ли столкнетесь с чем-то еще, кроме self.

Заключение

Сегодня вы узнали, что “self” делает в классе Python.

Напомним, что self в Python обозначает сам объект. Благодаря ему класс знает, как получить доступ к своим собственным атрибутам и методам.

При создании объекта вызывается метод __init__. В этом методе обычно присваиваются атрибуты экземпляру класса через self.

Обратите внимание, что “self” не является зарезервированным ключевым словом. Вместо него можно использовать любое другое слово, если передавать его в качестве первого аргумента для каждого метода класса. Однако  “self” настолько часто используется, что не следует использовать что-либо другое, даже если это возможно.

Спасибо, что прочитали. Надеюсь, вы нашли то, что искали. Удачного кодинга!

Перевод статьи «What Is ‘self’ in Python? A Complete Guide (with Examples)».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *