Глава 14 · Создаём объекты реального мира

self и связывание методов

rex.layat() и Sobaka.layat(rex) — один и тот же вызов. Разбираемся, откуда self берётся на самом деле.

Две равносильные записи одного вызова

rex.layat() — не единственный способ вызвать этот метод. Тот же самый вызов можно записать и через класс, передав объект вручную первым аргументом:

Одно и то же действие — два способа записи
Через объект (обычная запись)
rex.layat()
Через класс (то, что происходит на самом деле)
Sobaka.layat(rex)
Что использовать сегодня: На письме всегда используйте запись через объект — rex.layat(). Вторая форма показана только для того, чтобы стало видно, откуда берётся self: это и есть rex, переданный автоматически первым аргументом.

Что происходит при вызове rex.layat()

rex.layat()вызов через точкуPython ищетlayatв классе Sobakaнаходитlayat(self)метод определён вклассеself = rexподставляетсяавтоматическитело методавыполняетсяс доступом кself.klichka и т.д.
Связывание метода: объект слева от точки становится self внутри метода
self — снова не ключевое слово
Как уже говорилось в разделе 14.3: self — это просто имя первого параметра метода, выбранное по соглашению. Python подставляет в него объект слева от точки НЕЗАВИСИМО от того, как вы его назвали — но называйте его self всегда, это единственное имя, которое ожидает увидеть любой человек, читающий код на Python.
Debug Lab 1: забыли self в определении метода
bez_self.py
class Sobaka:
    def __init__(self, klichka):
        self.klichka = klichka

    def layat():          # забыли self первым параметром
        print("Гав-гав!")

rex = Sobaka("Рекс")
rex.layat()
Traceback (most recent call last):
  File "bez_self.py", line 9, in 
    rex.layat()
TypeError: Sobaka.layat() takes 0 positional arguments but 1 was given
Что видно на экране

Python всё равно попытался подставить rex первым аргументом при вызове rex.layat() — связывание метода происходит ВСЕГДА, а не только когда вы этого ожидаете. Раз в определении метода не было параметра, чтобы его принять, — Python сообщает, что аргументов передано на один больше, чем метод способен принять.

Исправленный код
s_self.py
class Sobaka:
    def __init__(self, klichka):
        self.klichka = klichka

    def layat(self):
        print(f"{self.klichka}: Гав-гав!")

rex = Sobaka("Рекс")
rex.layat()
Практика: self и связывание методов
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →