Правильное использование self и методов класса в Python

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для устранения ошибки TypeError: Missing 1 required positional argument: 'self', необходимо сначала создать экземпляр класса, затем вызвать его метод:

Python
Скопировать код
class MyClass:
    def my_method(self):
        print("Здравствуйте")

# Правильное применение:
bob_the_object = MyClass()  # Познакомьтесь, это Боб – экземпляр класса.
bob_the_object.my_method()  # Бобу поручено поприветствовать вас!

Вызов метода через экземпляр класса bob_the_object.my_method() корректно связывает self с объектом bob_the_object.

Параметр self в контексте вызываемого метода обозначает экземпляр класса. Если забыть присвоить объект переменной self, то мы получим TypeError, так как Python благодаря методу экземпляра автоматически и ожидает self.

Кинга Идем в IT: пошаговый план для смены профессии

Последствия отсутствия self

Пропуск self при вызове метода класса экземпляра приведет к ошибке. Это эквивалентно попытке использовать метод класса вместо экземпляра, что является семантически некорректным для нестатических методов.

Создание экземпляров при помощи конструкторов классов

Конструктор __init__ важен, так как с помощью self производится инициализация атрибутов экземпляра:

Python
Скопировать код
class MyClass:
    def __init__(self, data):
        self.data = data   # Вот так атрибут 'data' становится частью 'self'

Это позволяет создавать объекты с уникальными данными и обеспечивает возможность самому объекту контролировать свое внутреннее состояние.

Доступ к атрибутам экземпляра через self

С помощью self осуществляется доступ и изменение состояния объекта, что является основным принципом объектно-ориентированного программирования:

Python
Скопировать код
class MyClass:
    def set_data(self, data):
        self.data = data  # теперь 'data' связан с 'self'

Классы и статические методы: краткий обзор

Классовые методы принимают cls в качестве первого аргумента, который представляет класс в целом. Статические методы не используют параметр self, поскольку они не предусматривают работы непосредственно с экземплярами или классом.

Python
Скопировать код
class MyClass:
    @classmethod
    def clan_method(cls):  # cls обозначает класс, а не отдельный экземпляр
        pass

    @staticmethod
    def lair_method():  # Этот метод-одиночка не требует 'self' или 'cls'
        pass

Распространенные ошибки новичков

Остерегайтесь предложений IDE, таких как PyCharm

Иногда интегрированные среды разработки, вроде PyCharm, могут предложить добавить аннотацию @staticmethod, но не спешите! Сначала попытайтесь разобраться в разнице между типами методов, а затем применяйте знания на практике.

Пропуск ключевого слова self в определениях методов

Определение метода без указания self — типичная ошибка для начинающих:

Python
Скопировать код
class MyClass:
    def my_method():  # Кажется, 'self' отсутствует!
        print("Здравствуйте")

Вызов классового метода вместо экземпляра приводит к ошибке:

Python
Скопировать код
MyClass.my_method()  # Вызовет ошибку TypeError, так как нам нужен экземпляр класса

Визуализация

Представьте, что вы заказываете такси через мобильное приложение:

Markdown
Скопировать код
Мобильное приложение (📲): "Привет, такси (🚖), можешь подъехать за этим клиентом (🙋‍♂️)?"

В этом контексте отсутствие 'self' выглядит так:

Python
Скопировать код
Такси.поехать();  # Кто именно заказал? Где именно находится клиент?
Markdown
Скопировать код
📲: "Привет, ... ты можешь подъехать за ...?"
🚖: "😕"

Для того чтобы забрать клиента, необходимо, чтобы было отдельно указано такси (🚖) (это и есть self) и конкретный клиент (🙋‍♂️).

Корректное использование с 'self':

Python
Скопировать код
moje_taksi.pick_up(klient);  // Отлично, такси (🚖) может подъехать за клиентом (🙋‍♂️)!
Markdown
Скопировать код
📲: "Приветствую, такси (🚖), можешь подъехать за этим клиентом (🙋‍♂️)?"
🚖: "🚀"

Если вызвать такси без указания self, то получите билет в город ошибок TypeError!

Раскрытие тайны 'self'

'self': Почему его нельзя игнорировать

Каждый метод экземпляра класса требует self в качестве первого параметра. Это ссылка на экземпляр, связанный с вызовом метода, и при помощи этого мы можем получить доступ к атрибутам и другим методам объекта.

Создание экземпляров с помощью init

Создание объекта класса начинается с введения конструктора __init__, где вы задаете параметры для дальнейшего использования:

Python
Скопировать код
# Создание объекта через __init__
class MyClass:
    def __init__(self, attribute):
        self.attribute = attribute  # 'attribute' теперь в 'self'

baymax = MyClass("обнимашки")  # Знакомьтесь: это Баймакс, и его миссия – обнимашки.

Статические методы: в одиночестве в мире Python

Статические методы являются нечто особенным. Декоратор @staticmethod освобождает их от обязательства использовать self, тем самым создавая методы, которые относятся к классу, но не связаны с его экземплярами:

Python
Скопировать код
# Статические методы не требуют 'self'
class MyClass:
    @staticmethod
    def my_static_method():
        print("Я независим, мне не нужен self!")

Статические методы не могут непосредственно взаимодействовать с атрибутами экземпляра или класса. Их можно сравнить с уединенным мудрецом, который ценит свою независимость.

Классовые методы: руководители на производстве

Классовые методы, отмеченные @classmethod, полезны для работы со структурами класса, в частности, в фабричных паттернах:

Python
Скопировать код
class MyClass:
    @classmethod
    def factory(cls):  # cls отвечает за процесс создания
        return cls()   # Создает экземпляр класса

Правильное использование — залог безошибочности кода

Особое внимание следует уделять корректной декларации методов и правилам их вызова:

Python
Скопировать код
class MyClass:
    def __init__(self):
        self.data = "по умолчанию"  # Зададим значение "по умолчанию" для 'data'

    def set_data(self, value):
        self.data = value  # 'value' cтановится значением 'data''

gru = MyClass()
gru.set_data("новый миньон")  # Теперь у Грю появился новый миньон

Неаккуратное обращение с методами и экземплярами может легко провоцировать появление ошибки TypeError.

Полезные материалы

  1. 9. Классы — Python 3.12.2 Documentation — Основы работы с классами и объектами в Python.
  2. Understanding Class and Instance Variables in Python 3 | DigitalOcean — Детальный разбор классовых и экземплярных переменных.
  3. Instance, Class, and Static Methods — Demystified – Real Python — Глубокое погружение в различные типы методов Python.
  4. Object-Oriented Programming (OOP) in Python 3 – Real Python — Незаменимая информация об объектно-ориентированном программировании на Python.
  5. Python Class Attributes: An Overly Thorough Guide — Тщательное руководство по атрибутам класса и их применению.
  6. Learning Python 3 | Codecademy — Практические занятия по работе с классами в Python, идеальные для закрепления приобретенных навыков.