Методы экземпляра: self и работа с внутренним состоянием объекта
Что такое методы экземпляра и зачем нужен self?
Методы экземпляра — это функции, которые работают с конкретным объектом класса. Они получают доступ к его данным (атрибутам) и могут изменять их.
📌 Ключевая особенность: Первый параметр метода — всегда self. Это ссылка на текущий экземпляр класса.
class Cat:
def __init__(self, name):
self.name = name # сохраняем имя во внутреннем состоянии
def meow(self): # метод экземпляра
print(f"{self.name} говорит: Мяу!")
my_cat = Cat("Барсик")
my_cat.meow() # Барсик говорит: Мяу!
Через self метод получает доступ к атрибутам (name) и другим методам объекта. Без него Python не понимал бы, с каким конкретно котом работать.
Как self связывает методы и данные?
self — это мост между методами и внутренним состоянием объекта.
🔍 Пример с изменением состояния:
class BankAccount:
def __init__(self, balance):
self.balance = balance
def deposit(self, amount):
self.balance += amount
print(f"Пополнение: +{amount}. Новый баланс: {self.balance}")
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
print(f"Снятие: -{amount}. Остаток: {self.balance}")
else:
print("Недостаточно средств!")
account = BankAccount(1000)
account.deposit(500) # Пополнение: +500. Новый баланс: 1500
account.withdraw(200) # Снятие: -200. Остаток: 1300
Здесь deposit и withdraw меняют self.balance — внутреннее состояние объекта.
Практика: методы экземпляра в реальных задачах
Пример 1: Управление состоянием игрового персонажа
class Player:
def __init__(self, name, health=100):
self.name = name
self.health = health
def take_damage(self, damage):
self.health -= damage
if self.health <= 0:
print(f"{self.name} повержен!")
else:
print(f"У {self.name} осталось {self.health} HP")
def heal(self, amount):
self.health += amount
print(f"{self.name} восстановил {amount} HP. Теперь у него {self.health} HP")
hero = Player("Артур")
hero.take_damage(30) # У Артура осталось 70 HP
hero.heal(20) # Артур восстановил 20 HP. Теперь у него 90 HP
Пример 2: Корзина покупок
class ShoppingCart:
def __init__(self):
self.items = []
def add_item(self, product, price):
self.items.append((product, price))
print(f"Добавлен: {product} за {price} руб.")
def total(self):
return sum(price for _, price in self.items)
def checkout(self):
total = self.total()
print(f"Итого к оплате: {total} руб.")
self.items = [] # очищаем корзину после оплаты
cart = ShoppingCart()
cart.add_item("Ноутбук", 50000) # Добавлен: Ноутбук за 50000 руб.
cart.add_item("Мышь", 2000) # Добавлен: Мышь за 2000 руб.
cart.checkout() # Итого к оплате: 52000 руб.
Частые ошибки и как их избежать
❌ Забыли self в определении метода:
def greet(): # Ошибка! Нет self.
print(f"Привет, {self.name}") # NameError: name 'self' is not defined
✅ Правильно:
def greet(self):
print(f"Привет, {self.name}")
❌ Путаница между атрибутами класса и экземпляра:
class Dog:
tricks = [] # атрибут класса (общий для всех экземпляров)
def add_trick(self, trick):
self.tricks.append(trick) # изменяет список для всех собак!
dog1 = Dog()
dog2 = Dog()
dog1.add_trick("лай")
print(dog2.tricks) # ['лай'] 😱
✅ Решение — использовать атрибут экземпляра:
class Dog:
def __init__(self):
self.tricks = [] # свой список для каждой собаки
def add_trick(self, trick):
self.tricks.append(trick)
dog1 = Dog()
dog2 = Dog()
dog1.add_trick("лай")
print(dog2.tricks) # [] 👍
Итоги
self— обязательный первый аргумент методов экземпляра, ссылается на текущий объект.- Через
selfможно читать и изменять внутреннее состояние объекта. - Методы экземпляра — главный инструмент для инкапсуляции логики работы с данными объекта.
💡 Совет от Данилы Бежина: Если хотите глубже разобрать ООП в Python, посмотрите уроки на YouTube.
Попробуйте создать класс с методами для своей задачи — например, для управления задачами в TODO-листе или моделирования физического объекта!