Язык программирования Python

Что означает self в Python?

В Python self является причиной многих проблем для разработчиков, которые занимаются объектно-ориентированным программированием, давайте попробуем разобраться в этом вопросе!

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

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

Это ошибка!

Очень важно, чтобы вы понимали, что означает это “self” и почему оно полезно при разработке на Python.

Это ключевое понятие в объектно-ориентированном программировании, которое вам необходимо понять!

Создадим класс

Допустим, вы фанат велоспорта и хотите создать программу для борьбы с вашей всепоглощающей зависимостью от облегающих спортивных шорт:

class Velo: wheels = 2 def __init__(self, brand, price, weight): self.brand = brand self.price = price self.weight = weight velo = Velo(self="Peugeot", price=500, weight=100)

Для начала я напомню вам разницу между переменной экземпляра и переменной класса, чтобы вам было понятнее:

Переменные класса – это переменные, которые являются общими для всех экземпляров вашего класса.

В нашем классе Velo переменная wheels является переменной класса.

Это вполне логично, потому что почти все велосипеды работают на двух колесах и не более, если только вы не живете в Юго-Восточной Азии и не ездите регулярно на тук-туке.

Мы определяем их внутри класса, но вне всех остальных методов!

Примечание. Внутри класса мы говорим уже не о функциях, а о методах.

С другой стороны, у нас есть переменные экземпляра, значения которых отличаются от экземпляра к экземпляру.

В нашем примере переменные self.brand, self.price и self.weight являются переменными экземпляра.

Как вы можете видеть, они определяются внутри метода init.

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

Поэтому вы должны вложить все, что свойственно объекту, который вы хотите создать.

Давайте посмотрим, что произойдет, если я создам два экземпляра класса Velo и попытаюсь получить доступ к этим переменным:

class Velo: wheels = 2 def __init__(self, brand, price, weight): self.brand = brand self.price = price self.weight = weight velo_01 = Velo("btwin", 250, 15) velo_02 = Velo("rockrider", 170, 12) print(velo_01.wheels) # 2 print(velo_02.wheels) # 2 print(velo_01.brand) # btwin print(velo_02.brand) # rockrider'

Как я уже сказал, все экземпляры имеют доступ к переменным класса, вот почему два моих велосипеда имеют по два колеса, и мне не нужно ничего указывать.

Однако вы можете видеть, что каждый велосипед имеет свой собственный бренд, потому что это два разных экземпляра!

В чем цель self?

Когда я создавал свой метод init, вы заметили, что в дополнение к параметрам я добавил слово self.

Я также использовал его для определения переменных экземпляра.

Зачем?

Self используется для представления экземпляра класса! Благодаря ему я могу получить доступ к атрибутам и методам своего класса.

Давайте создадим метод экземпляра, чтобы вы могли увидеть это на практике:

class Velo: wheels = 2 def __init__(self, brand, price, weight): self.brand = brand self.price = price self.weight = weight def drive(self): print("Лучший велосипед: {} !".format(self.brand)) velo_01 = Velo("btwin", 250, 15) velo_02 = Velo("rockrider", 170, 12) print(velo_01.wheels) # 2 print(velo_02.wheels) # 2 print(velo_01.brand) # btwin print(velo_02.brand) # rockrider velo_01.drive() # Лучший велосипед: btwin ! velo_02.drive() # Лучший велосипед: rockrider !

Я создал метод drive в классе Velo и указал self в качестве первого параметра:

def drive(self): print("Лучший велосипед: {} !".format(self.brand))
Code language: PHP (php)

Поэтому я могу вызвать этот метод drive на всех созданных мною экземплярах.

Примечание. Обратите внимание, что вам не нужно явно использовать слово self, поскольку оно не является зарезервированным словом в Python. Если вы пришли из другого языка программирования, например, JavaScript, вам, возможно, привычнее это использовать. Поэтому вы можете использовать Maria вместо self, и это будет работать точно так же.

В Python мы традиционно используем слово self, но вы можете поступать так, как хотите (мы не советуем, даже если нам нравится Мария )!

С другой стороны, есть правило, которое вы должны соблюдать абсолютно точно:

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

Секрет self

Возможно, вы заметили, но в последнем примере я вызвал метод drive без передачи каких-либо аргументов, и все же код сработал. Мне удалось вывести сообщение с брендом велосипеда текущего экземпляра.

Вы можете задаться вопросом, как мой метод drive знает, что нужно использовать атрибуты именно этого экземпляра, а не другого?

Я думаю, вы поняли, это все self!

Когда я это делаю:

velo_01.drive()
Code language: CSS (css)

Вот что происходит за кулисами:

Velo.drive(velo_01)
Code language: CSS (css)

Интерпретатор Python автоматически выполняет “преобразование” за вас!

С одной стороны, это делает ваш код более эстетичным, а с другой – облегчает жизнь, когда вы хотите наследовать свой класс от других классов.

И, очевидно, если вы забудете добавить self при определении метода экземпляра, у вас возникнут небольшие проблемы, когда вы захотите его использовать:

def drive(): print("Лучший велосипед: {} !".format(self.brand)) velo_01.drive() #TypeError: drive() takes 0 positional arguments but 1 was given
Code language: CSS (css)

Эта ошибка часто непонятна людям, не привыкшим к объектно-ориентированному программированию.

Python сообщает нам, что методу drive был передан аргумент (1 was given), однако, если посмотреть на наш код, мы не передаем никакого аргумента.

velo_01.drive()
Code language: CSS (css)

Как мы только что видели выше, в фоновом режиме Python использует ваш класс для выполнения метода drive и автоматически передает экземпляр в качестве первого аргумента.

Итак, аргумент передается методу drive, просто вы этого не видите, и это делаете не вы, Python сам об этом позаботится.

# Используем метод drive для экземпляра velo_01.drive() # Это то же самое, что пройти через класс и передать экземпляр Velo.drive(velo_01)
Code language: CSS (css)

Поэтому вы должны указать self в качестве первого параметра в определении метода drive, чтобы использовать его с экземпляром velo_01.

Один комментарий к “Что означает self в Python?

  1. В первом примере:
    velo = Velo(self=”Peugeot”, price=500, weight=100)
    наверное всё же brand=”Peugeot”

Добавить комментарий

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