Объектно-ориентированное программирование (ООП) — это метод структурирования программы путем упаковки связанных свойств и поведения в отдельные объекты. В нашем небольшом учебнике вы изучите основы объектно-ориентированного программирования в Python. Мы постарались объяснить просто и последовательно традиционно трудные для понимания новичков концепции ООП, чтобы юные любители «питона» сразу после прочтения смогли начать строить свои объекты и писать новые классы.
Концептуально объекты похожи на компоненты системы. Представьте себе программу в виде своеобразного заводского сборочного конвейера. На каждом этапе конвейера компонент системы обрабатывает некоторый материал, в конечном итоге превращая сырье в готовый продукт.
Объект содержит данные, например, предварительно обработанные материалы на каждом этапе сборочного конвейера, а также типовое поведение (например, действия, которые выполняет каждый компонент сборочного конвейера).
В этом мануале из двух частей вы узнаете, как:
Объектно-ориентированное программирование — это парадигма программирования, которая позволяет структурировать программы таким образом, что свойства и поведение объединяются в отдельные объекты.
Например, объект может представлять человека с такими свойствами, как имя, возраст и адрес, и такими поведенческими характеристиками, как ходьба, разговор, дыхание и бег. Или он может представлять электронное письмо с такими свойствами, как список получателей, тема и тело, а также с такими поведениями, как добавление вложений и отправка.
Говоря иначе, объектно-ориентированное программирование — это подход к моделированию конкретных, реальных вещей, таких как автомобили, а также отношений между вещами, такими как компании и сотрудники, студенты и преподаватели и так далее. ООП моделирует объекты реального мира как программные объекты, которые имеют некоторые данные, связанные с ними, и могут выполнять определенные функции.
Другой распространенной парадигмой программирования является процедурное программирование, которое структурирует программу как рецепт, предоставляя набор шагов в виде функций и блоков кода, которые последовательно выполняются для выполнения задачи.
Ключевым моментом является то, что объекты находятся в центре объектно-ориентированного программирования в Python, не только представляя данные, как в процедурном программировании, но и в общей структуре программы.
Примитивные структуры данных — числа, строки и списки — предназначены для представления простых фрагментов информации, таких как стоимость яблока, название стихотворения или ваши любимые цвета, соответственно. А что если вам нужно представить что-то более сложное?
Например, предположим, вы хотите отслеживать сотрудников организации. Вам нужно хранить некоторую базовую информацию о каждом сотруднике, такую как его имя, возраст, должность и год начала работы. Понятно, что таких сотрудников (со всем набором перечисленных свойств) будет много.
Один из способов сделать это — представить каждого сотрудника в виде списка:
kirk = ["James Kirk", 34, "Captain", 2265] spock = ["Spock", 35, "Science Officer", 2254] mccoy = ["Leonard McCoy", "Chief Medical Officer", 2266]
Такой подход имеет ряд проблем.
Во-первых, он может усложнить управление большими файлами кода. Если вы ссылаетесь на kirk[0]
в нескольких строках от места объявления списка kirk
, вспомните ли вы, что элемент с индексом 0 — это имя сотрудника?
Во-вторых, это может привести к ошибкам, если не каждый сотрудник имеет одинаковое количество элементов в списке. В приведенном выше списке у mccoy
отсутствует возраст, поэтому mccoy[1]
вернет «Главный врач» вместо возраста доктора Маккоя.
Отличный способ сделать код такого типа более управляемым и удобным для сопровождения — использовать классы.
Классы используются для создания определяемых пользователем структур данных. Кроме того, классы определяют функции, называемые методами, которые определяют поведение и действия, которые объект, созданный на основе класса, может выполнять с его данными.
В этом учебнике в качестве упражнения вы создадите класс Dog, который будет хранить информацию о характеристиках и поведении отдельных собак.
Класс — это схема того, как что-то должно быть определено. На самом деле он не содержит никаких данных. Класс Dog указывает, что для определения собаки необходимы имя и возраст, но он не содержит ни имени, ни возраста конкретной собаки.
В то время как класс — это чертеж, экземпляр класса — это объект, созданный на основе класса и содержащий реальные данные. Экземпляр класса Dog — это уже не чертеж. Это вполне реальная модель собаки со своим персональным именем, например Майлз, которому четыре года.
Говоря иначе, класс — это как форма или анкета. Экземпляр — это как форма, заполненная информацией. Как многие люди могут заполнить одну и ту же анкету своей собственной уникальной информацией, так и из одного класса можно создать множество разных экземпляров.
Все определения классов начинаются с ключевого слова class
, за которым следует имя класса и двоеточие. Любой код, расположенный с отступом ниже определения класса, считается частью тела класса.
Вот пример класса Dog:
class Dog: pass
Тело класса Dog состоит из единственного оператора: ключевого слова pass
.
pass
часто используется как заполнитель, указывающий, куда в конечном итоге пойдет код. Оно позволяет выполнить этот код без того, чтобы Python выдал ошибку.
Примечание: По традиции имена классов Python записываются в нотации CapitalizedWords. Например, класс для конкретной породы собак, такой как Джек Рассел Терьер, будет записан как JackRussellTerrier.
Класс Dog сейчас не очень интересен, поэтому давайте немного приукрасим его, определив некоторые свойства, которыми должны обладать все объекты Dog. Есть несколько свойств, которые мы можем выбрать, включая имя, возраст, цвет шерсти и породу. Для простоты далее мы будем использовать только имя и возраст.
Свойства, которыми должны обладать все объекты Dog, определяются в методе под названием .__init__()
. Каждый раз, когда создается новый объект Dog, .__init__()
устанавливает начальное состояние этого объекта, присваивая значения свойств объекта. То есть .__init__()
автоматически инициализирует каждый новый экземпляр класса.
Вы можете задать .__init__()
любое количество параметров, но первым параметром всегда будет переменная self
. Когда создается новый экземпляр класса, он автоматически передается параметру self
в .__init__()
, чтобы можно было определить новые атрибуты объекта.
Давайте обновим класс Dog методом .__init__()
, который создает атрибуты .name
и .age
:
class Dog: def __init__(self, name, age): self.name = name self.age = age
Обратите внимание, что подпись метода .__init__()
отделена четырьмя пробелами. Отступ от тела метода составляет восемь пробелов. Этот отступ жизненно важен. Он сообщает Python, что метод .__init__()
принадлежит классу Dog.
В теле метода .__init__()
есть два утверждения, использующие переменную self
:
name = name
создает атрибут name
и присваивает ему значение параметра name
.age = age
создает атрибут под названием age
и присваивает ему значение параметра age
.Атрибуты, созданные в .__init__()
, называются атрибутами экземпляра. Значение атрибута экземпляра специфично для конкретного экземпляра класса. Все объекты Dog имеют имя и возраст, но значения атрибутов имени и возраста будут отличаться в зависимости от экземпляра Dog.
С другой стороны, атрибуты класса — это атрибуты, которые имеют одинаковое значение для всех экземпляров класса. Вы можете определить атрибут класса, присвоив значение имени переменной вне .__init__()
.
Например, следующий класс Dog имеет атрибут класса под названием species
со значением «Canis familiaris»:
class Dog: # Class attribute species = "Canis familiaris" def __init__(self, name, age): self.name = name self.age = age
И снова напомним три принципиальных момента:
Теперь, когда у нас есть класс Dog, давайте самостоятельно, в качестве домашнего задания, создадим несколько собак!
Давайте сделаем что-то типа финальной шпоры по OOP в «питоне», чтобы вы могли глазами объять весь этот длинный материал за раз.
Итак, вот словарик/определения ключевых понятий, которые мы узнали:
Класс
Класс — это чертеж объекта. Мы можем думать о классе как о наброске попугая с метками. Он содержит все подробности о названии, цветах, размере и т.д. каждого отдельного попугая. На основе этих описаний мы можем изучать попугая. Здесь попугай — это объект, то есть экземпляр или реализация класса.
Объект
Объект (экземпляр) — это инстанция класса («инстанс» объекта). Когда определяется класс, определяется только описание объекта, это просто некий паттерн. Поэтому не выделяется память или хранилище. А вот реальные объекты – они уже занимают память, да.
Методы
Методы — это функции, определенные в теле класса. Они используются для определения поведения объекта, доступных для него действий.
Наследование
Наследование — это способ создания нового класса для использования деталей существующего класса без его модификации. Вновь созданный класс является производным классом (или дочерним классом). Аналогично, существующий класс является базовым классом (или родительским классом). Обычно дочерний класс как-то расширяет функционал базового класса, является доработкой на базе первоначального класса.
Инкапсуляция
Используя ООП в Python, мы можем ограничить доступ к методам и переменным. Это предотвращает прямую модификацию данных, что называется инкапсуляцией. В Python мы обозначаем приватные атрибуты, используя подчеркивание в качестве префикса, т.е. используем одинарный _
или двойной __
.
Полиморфизм
Полиморфизм — это возможность (в ООП) использовать общий интерфейс для нескольких форм (типов данных).
Предположим, нам нужно раскрасить фигуру, есть несколько вариантов формы (прямоугольник, квадрат, круг). Однако мы можем использовать один и тот же метод для раскрашивания любой фигуры. Эта концепция «универсализации метода» называется полиморфизмом.
Помимо новой терминологии, которую мы перечислили выше, выделим также ключевые моменты для запоминания:
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…