Codebra
29 января 2026 в 18:34

Урок 63. Основы объектно-ориентированного программирования (ООП) в Python

В этом уроке начнем изучение объектно-ориентированного программирования (ООП) в Python. Узнаем о классах, его методах и атрибутах, а также об основных концепциях ООП.
📝

Внимание! На этой странице вы найдете материал урока из архивного курса по Python. Курс был написан в 2024 году и по-прежнему актуален для начинающих разработчиков.

Теоретический материал сохранен в исходном виде, а практические задания с автоматической проверкой вынесены в отдельные интенсивы и задания.

Полный список уроков доступен по тегу Архивный курс по Python и на странице первого урока.

📝 Кратко
  • В Python классы являются механизмом для создания новых объектов с возможностью наследования.
  • Классы помогают разбить программу на независимые части для уменьшения избыточности кода и повторного использования.
  • Python предоставляет возможность перегрузки операторов для настройки поведения методов класса.
  • Конструктор класса - это метод, вызываемый при создании экземпляра класса.
  • ООП в Python упрощает построение и поддержку больших программ, экономя время.

Введение

В предыдущем разделе мы разобрались с модулями и пакетами в Python. Начиная с этого урока, мы погрузимся в объектно-ориентированное программирование (ООП) в Python.

Ранее мы все называли «объектами» в общем смысле. В этом разделе начнем изучать классы Python – механизм для создания новых объектов, поддерживающих наследование. Класс - столп объектно-ориентированного программирования, помогающий разбить большую программу на смысловые независимые части для уменьшения избыточности кода и возможности повторного использования путем настройки кода, а не переписывания его. На первый взгляд, это может напоминать функции, но на самом деле класс более гибкий инструмент.

Python является таким языком, в котором применение ООП не является обязательным, особенно в начале изучения (а если вы на этом уроке, то уже давно не в начале изучения языка Python), так как чаще всего достаточно применение простых конструкций, например, функций. Если программа начинает разрастаться, то уже стоит задуматься о применении ООП, при надлежащем применении которого можно значительно уменьшить время разработки и упростить дальнейшую поддержку и модернизацию существующего кода.

Если рассматривать программу как автомобиль, то отдельные ее составные части могут быть классами, выражаясь в терминах ООП – это композиция. Четыре колеса можно описать одним классом, в котором есть два метода класса (пока определим это понятие как функция, находящаяся внутри класса): вращение колеса вперед и назад и один атрибут класса (пока определим, как переменные внутри класса): давление в шинах.

Все четыре колеса могут вращаться как вперед, так и назад. Два из них могут поворачиваться влево/вправо. Отвлечемся и посмотрим на пример класса Wheel. Кстати, пользовательские классы принято называть с заглавной буквы.

class Wheel:
    pressure = 2.0

    def forward_rotation(self):
        pass

    def backwards_rotation(self):
        pass

Чтобы решить проблему с поворотом колес влево/вправо, просто дописать два метода в этот класс недопустимо, так как таким образом получается, что и задние колеса могут поворачиваться. Можно создать второй класс, который будет дублировать два метода и атрибут и к тому же иметь два дополнительных метода, связанных с поворотом колес. Предположим, мы сделаем так и в какой-то момент нам станет нужно добавить новый атрибут, обозначающий диаметр дисков. Нам придется добавить этот атрибут в оба класса. Так можно и запутаться или забыть что-то куда-то дописать. Отметаем этот вариант. Остается наследование. Мы можем создать класс с общими свойствами, как класс Wheel и наследовать от него другие классы FrontWheel и BackWheel, которые будут обладать теми же методами/аргументами класса Wheel и иметь свои специализированные. Такой способ сведет к минимуму дублирование кода и упростит внесение общих изменений. Подробнее про наследование будем говорить позднее.

Классы напоминают модули и функции, они точно так же являются средством для упаковки логики и данных и определяют новое пространство имен. Но есть отличия. Во-первых, у одного класса может быть несколько экземпляров (объект, обладающий свойствами класса). Для примера давайте создадим четыре колеса (экземпляра) от класса Wheel:

fl = Wheel()
fr = Wheel()
bl = Wheel()
br = Wheel()

Далее можем вращать левое переднее колесо вперед и узнать его давление:

fl.forward_rotation()
print(fl.pressure) # => 2.0

Во-вторых, классы в отличие от функций и модулей поддерживают наследование. В-третьих, классы поддерживают перегрузку операторов, позволяющую задать свою реализацию для какого-либо метода (подробнее об этом будет говорить позднее).

Если вы внимательно рассмотрели пример класса Wheel, то заметили: метод не совсем обычная функция. Метод класса должен иметь первый аргумент self (для получения объекта, на котором был произведен вызов). Рассмотрим пример:

class Hello:
    def print_name(self, name):
        print(name)

user = Hello()
user.print_name('Иван')

В первый аргумент self не нужно ничего передавать. Имя «Иван» было передано первому аргументу, сразу после self.

Конструктор класса и перегрузка операций

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

class Hello:
    name = ''
    def setname(self, n):
        name = n

user_1 = Hello()
user_2 = Hello()

user_1.setname('Иван')
user_2.setname('Петр')

print(user_1.name)

Почему ничего не вывелось? Чтобы обратиться к атрибуту класса, необходимо использовать ключевое слово self. Исправим наш код:

class Hello:
    name = ''
    def setname(self, n):
        self.name = n

Теперь плавно переходим к конструктору класса. Каждый раз, когда экземпляр (в примере выше user_1) генерируется из класса, Python вызывает метод __init__ - конструктор класса. Конструктор класса __init__ может не указываться явно, как это было в примерах выше. Рассмотрим пример с явным указанием конструктора класса, который принимает один параметр и устанавливает его в атрибут name.

class Hello:
    name = ''
    def __init__(self, n):
        self.name = n

    def print_name(self):
        print(self.name)

user_1 = Hello('Иван')
user_1.print_name()

Обратите внимание на строку создания экземпляра класса, а именно на то, как и куда передаем параметр «Иван». Этот пример показывает не только работу конструктора класса, но и перегрузку операторов, о которой мы будем боле подробно говорить в дальнейшем.

В этом уроке мы очень кратко познакомились с классами и ООП, чтобы только очертить наше дальнейшее изучение. Как вы наверняка поняли, ООП – это способ упростить построение и поддержку больших программ, тем самым сэкономив время. В следующем уроке продолжим учиться писать классы, поговорим о перегрузке операторов и наследовании.

📝

Переходите к следующему уроку курса, а так же не забудьте посмотреть новый материал на Codebra по тегу Python.