Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что передает 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() |
| Изменение state | self.value = new_value |
| Различие объектов | Каждый объект имеет свой self |
| Единство | Все методы одного объекта используют один self |
Вывод
self — это ссылка на текущий экземпляр объекта. Она передаётся автоматически Python и позволяет:
- Обращаться к атрибутам объекта
- Вызывать другие методы объекта
- Изменять состояние объекта
- Различать объекты разных экземпляров
Это основа объектно-ориентированного программирования в Python.