← Назад к вопросам

Что передает self?

1.6 Junior🔥 211 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что передает self в Python

Это один из самых фундаментальных концептов в объектно-ориентированном Python. self — это просто параметр, который представляет текущий экземпляр объекта (instance). Объясню подробно.

Основная идея

Когда вы вызываете метод объекта, Python автоматически передаёт сам объект как первый параметр:

class Person:
    def __init__(self, name):
        self.name = name
    
    def greet(self):
        return f"Привет, я {self.name}"

# Создаём объект
person = Person("Иван")

# Эти два варианта эквивалентны:
# Вариант 1: Обычный вызов (Python передаёт self автоматически)
print(person.greet())  # "Привет, я Иван"

# Вариант 2: Явный вызов (низкоуровневый способ)
print(Person.greet(person))  # "Привет, я Иван"
# Видите? Мы явно передали объект person как self

Ключевой момент: self — это просто переменная, которая ссылается на текущий объект.

Как это работает под капотом

class Dog:
    def __init__(self, name):
        self.name = name  # self.name = "Рекс"
    
    def bark(self):
        return f"{self.name} гавкает!"

dog = Dog("Рекс")

# Когда вы пишите:
dog.bark()

# Python ВНУТРИ делает:
# 1. Берёт объект dog
# 2. Находит метод bark в классе Dog
# 3. Вызывает: Dog.bark(dog)  <- передаёт dog как self
# 4. Внутри метода self = dog
# 5. Возвращает "Рекс гавкает!"

# Это эквивалентно:
print(Dog.bark(dog))  # "Рекс гавкает!"

self содержит ВСЕ атрибуты объекта

class Car:
    def __init__(self, brand, model, year):
        # self это текущий объект, и мы добавляем ему атрибуты
        self.brand = brand
        self.model = model
        self.year = year
    
    def info(self):
        # self предоставляет доступ ко ВСЕМ атрибутам объекта
        return f"{self.year} {self.brand} {self.model}"
    
    def set_brand(self, new_brand):
        # self позволяет изменять атрибуты объекта
        self.brand = new_brand

car = Car("Toyota", "Camry", 2020)

# Все эти атрибуты доступны через self:
print(car.info())      # "2020 Toyota Camry"
car.set_brand("BMW")   # Изменили self.brand
print(car.info())      # "2020 BMW Camry"

self в разных контекстах

1. Экземплярные методы (instance methods)

class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade
    
    def get_info(self):  # self — это экземпляр Student
        return f"{self.name}: {self.grade}"

student = Student("Alice", "A")
print(student.get_info())  # self = student

2. Методы класса (class methods)

class Animal:
    species = "Unknown"
    
    @classmethod
    def set_species(cls, species):  # cls — это класс, не self!
        cls.species = species

Animal.set_species("Dog")
print(Animal.species)  # "Dog"

3. Статические методы (static methods)

class Math:
    @staticmethod
    def add(a, b):  # Нет self и нет cls!
        return a + b

print(Math.add(5, 3))  # 8

Частая ошибка: забыть self

# ❌ ОШИБКА: забыли self
class BankAccount:
    def deposit(amount):  # Где self?!
        balance += amount

# Результат при вызове:
account = BankAccount()
account.deposit(100)
# TypeError: deposit() takes 1 positional argument but 2 were given
# Потому что Python передаёт account, но функция не ожидает параметр

# ✅ ПРАВИЛЬНО: добавили self
class BankAccount:
    def __init__(self):
        self.balance = 0
    
    def deposit(self, amount):  # Теперь self на месте
        self.balance += amount
        return self.balance

account = BankAccount()
print(account.deposit(100))  # 100

Множественные объекты — каждый имеет свой self

class Counter:
    def __init__(self):
        self.count = 0
    
    def increment(self):
        self.count += 1
        return self.count

# Создаём два объекта
counter1 = Counter()
counter2 = Counter()

# Каждый имеет СВОЙ self и СВОЙ count
print(counter1.increment())  # 1 (self.count = 1 в counter1)
print(counter1.increment())  # 2
print(counter2.increment())  # 1 (self.count = 1 в counter2, отдельный!)
print(counter1.increment())  # 3

# Видите? self.count хранится отдельно для каждого объекта
print(counter1.count)  # 3
print(counter2.count)  # 1

self позволяет изменять состояние объекта

class BankAccount:
    def __init__(self, owner):
        self.owner = owner
        self.balance = 0  # Начальный state
    
    def deposit(self, amount):
        self.balance += amount  # Изменяем state объекта
    
    def withdraw(self, amount):
        if amount <= self.balance:
            self.balance -= amount  # Изменяем state объекта
        else:
            raise ValueError("Недостаточно средств")
    
    def get_info(self):
        return f"{self.owner}: {self.balance}₽"

account = BankAccount("Ivan")
print(account.get_info())      # "Ivan: 0₽"
account.deposit(1000)          # self.balance изменился на 1000
print(account.get_info())      # "Ivan: 1000₽"
account.withdraw(300)          # self.balance изменился на 700
print(account.get_info())      # "Ivan: 700₽"

self vs имена переменных

# Имя параметра может быть ANY (не обязательно self)
class Person:
    def greet(this):  # this вместо self (не рекомендуется!)
        return f"Привет, я {this.name}"

person = Person()
person.name = "Мария"
print(person.greet())  # Работает! "Привет, я Мария"

# Но self — это соглашение (convention) в Python
# Другие разработчики будут удивлены видеть что-то другое

# ✅ ПРАВИЛЬНО: используй self (как все нормальные люди)
class Person:
    def greet(self):
        return f"Привет, я {self.name}"

self в сложных сценариях

1. Передача self в другие методы

class Game:
    def __init__(self, name):
        self.name = name
        self.score = 0
    
    def add_score(self, points):
        self.score += points
        self.check_win()  # Вызываем другой метод на том же объекте
    
    def check_win(self):
        if self.score >= 100:
            self.end_game()
    
    def end_game(self):
        print(f"{self.name} выиграла с {self.score} точками!")

game = Game("Alice")
game.add_score(150)  # self передаётся цепочкой методов

2. Возврат self для цепочки вызовов

class StringBuilder:
    def __init__(self):
        self.text = ""
    
    def append(self, s):
        self.text += s
        return self  # Возвращаем self для цепочки
    
    def add_space(self):
        self.text += " "
        return self
    
    def build(self):
        return self.text

result = StringBuilder().append("Hello").add_space().append("World").build()
print(result)  # "Hello World"

3. Сравнение объектов через self

class Person:
    def __init__(self, name):
        self.name = name
    
    def __eq__(self, other):  # other это другой объект
        if not isinstance(other, Person):
            return False
        return self.name == other.name  # Сравниваем self с other

person1 = Person("Alice")
person2 = Person("Alice")
person3 = Person("Bob")

print(person1 == person2)  # True (имена одинаковые)
print(person1 == person3)  # False

Итоговая таблица: что передаёт self?

ЧтоОписание
Текущий объектЭкземпляр класса, на котором вызван метод
Доступ к атрибутамself.name, self.count, и т.д.
Доступ к методамself.method()
Изменение stateself.value = new_value
Различие объектовКаждый объект имеет свой self
ЕдинствоВсе методы одного объекта используют один self

Вывод

self — это ссылка на текущий экземпляр объекта. Она передаётся автоматически Python и позволяет:

  • Обращаться к атрибутам объекта
  • Вызывать другие методы объекта
  • Изменять состояние объекта
  • Различать объекты разных экземпляров

Это основа объектно-ориентированного программирования в Python.