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

Что такое self в обычном методе класса?

1.0 Junior🔥 241 комментариев
#Python Core

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

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

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

self в методах класса Python

Определение

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

Как это работает

class Dog:
    def __init__(self, name, age):
        # self — это ссылка на конкретный объект Dog
        self.name = name
        self.age = age
    
    def bark(self):
        # self указывает на объект, который вызвал метод
        print(f"{self.name} говорит: Гав!")
    
    def have_birthday(self):
        # Изменяем атрибут конкретного объекта
        self.age += 1
        print(f"{self.name} теперь {self.age} лет")

# Создание экземпляров
dog1 = Dog("Шарик", 3)
dog2 = Dog("Рекс", 5)

# Вызовы методов
dog1.bark()  # Шарик говорит: Гав!
dog2.bark()  # Рекс говорит: Гав!

# dog1.bark() эквивалентно Dog.bark(dog1)
# dog2.bark() эквивалентно Dog.bark(dog2)
# Python автоматически передаёт экземпляр как первый аргумент

Механизм под капотом

class Cat:
    def meow(self):
        print(f"Имя: {self.name}")

cat = Cat()
cat.name = "Мурзик"

# Эти вызовы ЭКВИВАЛЕНТНЫ:
cat.meow()           # Python: Cat.meow(cat)
Cat.meow(cat)        # Явная передача экземпляра

# Без self вызов был бы:
# cat.meow()  # TypeError: meow() takes 0 positional arguments but 1 was given

self vs другие параметры

class Account:
    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance
    
    def transfer(self, other_account, amount):
        # self — счёт, с которого снимаем
        # other_account — счёт, на который переводим (тоже объект Account)
        # amount — сумма (просто число)
        
        if self.balance >= amount:
            self.balance -= amount
            other_account.balance += amount
            print(f"Переведено {amount} со счёта {self.owner} на {other_account.owner}")
        else:
            print("Недостаточно средств")

my_account = Account("Иван", 1000)
your_account = Account("Мария", 500)

my_account.transfer(your_account, 300)
# self = my_account, other_account = your_account, amount = 300

self необязательно называть self

class Person:
    def __init__(cls, name):  # Плохая практика! Вводит в заблуждение
        cls.name = name
    
    def greet(obj):
        print(f"Привет, я {obj.name}")

person = Person("Алекс")
person.greet()  # Привет, я Алекс

# Но это ОЧЕНЬ плохо читается. Используй self!

Разница между методами

class Calculator:
    total = 0  # Атрибут класса (общий для всех экземпляров)
    
    def add(self, x, y):
        # Обычный метод
        # self — текущий экземпляр
        return x + y
    
    @classmethod
    def reset_total(cls):
        # cls — сам класс (не экземпляр)
        cls.total = 0
    
    @staticmethod
    def multiply(x, y):
        # Ни self, ни cls
        # Функция, привязанная к классу
        return x * y

calc = Calculator()
print(calc.add(5, 3))              # 8 (self = calc)
print(Calculator.reset_total())    # cls = Calculator
print(calc.multiply(2, 3))         # 6 (статический метод)

self и изменение состояния

class BankAccount:
    def __init__(self, balance):
        self.balance = balance
    
    def deposit(self, amount):
        self.balance += amount  # Изменяем состояние конкретного объекта
        return self.balance
    
    def __str__(self):
        return f"Баланс: {self.balance}"

acc1 = BankAccount(1000)
acc2 = BankAccount(500)

print(acc1)  # Баланс: 1000
print(acc2)  # Баланс: 500

acc1.deposit(200)
print(acc1)  # Баланс: 1200
print(acc2)  # Баланс: 500 (не изменился!)

# self в методе deposit() относится к разным объектам
# Для acc1 — это acc1, для acc2 — это acc2

Типизация self

from typing import Self  # Python 3.11+

class Builder:
    def __init__(self, value: str = ""):
        self.value = value
    
    def append(self, text: str) -> Self:
        # Self указывает, что метод возвращает тот же класс
        self.value += text
        return self  # Возвращаем сам объект
    
    def build(self) -> str:
        return self.value

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

Частые ошибки

# ❌ Ошибка 1: забыли self
class BadClass:
    def method():  # Забыли self!
        print("Ошибка")

bad = BadClass()
bad.method()  # TypeError: method() takes 0 positional arguments but 1 was given

# ✅ Исправление
class GoodClass:
    def method(self):
        print("Успех")

# ❌ Ошибка 2: вызвали как static method
class Example:
    def __init__(self, value):
        self.value = value
    
    def get_value(self):
        return self.value

Example.get_value()  # TypeError: get_value() missing 1 required positional argument: 'self'

# ✅ Исправление
ex = Example(42)
print(ex.get_value())  # 42

Итоговое резюме

  • self — ссылка на текущий экземпляр класса
  • Первый параметр каждого обычного метода
  • Python передаёт его автоматически при вызове метода
  • Позволяет методу обращаться к атрибутам и другим методам объекта
  • Это просто соглашение — можно назвать иначе (но не стоит)
  • @classmethod использует cls, @staticmethod ничего не использует