Объектно-ориентированное программирование Python (ООП в Python)
В этой статье мы расскажем об объектно-ориентированном программировании (ООП) в Python и его фундаментальных концепциях.
Введение в ООП в Python
Python - это мультипарадигмальный язык. Это означает, что он поддерживает различные подходы к программированию.
Одной из наиболее популярных парадигм является создание объектов. Она известна как объектно-ориентированное программирование (ООП).
Объект имеет две характеристики:
- атрибуты;
- поведение;
Рассмотрим на примере:
Объект – это попугай:
- имя, возраст, цвет являются атрибутами;
- пение, танцы - это поведение;
Концепция ООП в Python направлена на создание кода для многократного использования. Эта концепция также известна как DRY (Don't Repeat Yourself).
В Python концепция ООП реализует несколько принципов:
Наследование | Использование элементов из нового класса без изменения существующего класса. |
Инкапсуляция | Скрытие приватных элементов класса от других объектов. |
Полиморфизм | Концепция использования объекта с одинаковым интерфейсом без получения информации о его типе и внутренней структуре. |
Класс
Мы можем представить класс как эскиз попугая с метками. Он содержит все данные об имени, цвете, размере и т. д. На основе этого описания можно изучить попугая. В данном случае попугай является объектом.
Примером для класса попугая может быть:
class Parrot:
pass
Мы используем ключевое слово class для определения пустого класса Parrot . Из класса мы создаем экземпляр – объект определенного класса.
Объект
Объект - это экземпляр класса. В определении класса задается только описание объекта. Пример создания объекта класса Parrot:
obj = Parrot()
В данном случае obj является объектом класса Parrot.
Предположим, что у нас есть информация о попугае. Теперь нужно показать, как построить класс и объекты Parrot.
Пример 1. Создание класса и объекта в Python
class Parrot:
# атрибут класса
species = "bird"
# атрибут экземпляра
def __init__(self, name, age):
self.name = name
self.age = age
# создаем экземпляр класс Parrot
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)
# получаем доступ к атрибутам класса
print("Blu is a {}".format(blu.__class__.species))
print("Woo is also a {}".format(woo.__class__.species))
# получаем доступ к атрибутам экземпляра
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))
Результат работы программы:
Blu is a bird
Woo is also a bird
Blu is 10 years old
Woo is 15 years old
Сначала мы создаем класс с именем Parrot. Затем мы определяем атрибуты. Они являются характеристикой объекта.
Затем мы создаем экземпляры класса Parrot. В данном случае blu и woo являются ссылками на новые объекты.
После этого мы получаем доступ к атрибуту класса с помощью __class __.species. Атрибуты класса одинаковы для всех его экземпляров. Точно так же мы получаем доступ к атрибутам экземпляра, используя blu.name и blu.age. Но атрибуты экземпляра уникальны для каждого экземпляра класса.
Методы
Методы - это функции, определенные внутри класса. Они используются для определения поведения объекта.
Пример 2: Создание методов в Python
class Parrot:
# атрибуты экземпляра
def __init__(self, name, age):
self.name = name
self.age = age
# метод экземпляра
def sing(self, song):
return "{} sings {}".format(self.name, song)
def dance(self):
return "{} is now dancing".format(self.name)
# создаем экземпляр объекта
blu = Parrot("Blu", 10)
# вызываем методы экземпляра
print(blu.sing("'Happy'"))
print(blu.dance())
Результат работы программы:
Blu sings 'Happy'
Blu is now dancing
В приведенном выше примере мы определяем два метода sing() и dance(). Их называют методами экземпляра, так как они вызываются для экземпляра объекта, то есть для blu.
Наследование
Наследование - это способ создания нового класса на основе старого. Новый класс является производным классом (дочерним). Существующий класс является базовым классом (родительским).
Пример 3: Использование наследования в Python
# родительский класс
class Bird:
def __init__(self):
print("Bird is ready")
def whoisThis(self):
print("Bird")
def swim(self):
print("Swim faster")
# дочерний класс
class Penguin(Bird):
def __init__(self):
# вызов функции super()
super().__init__()
print("Penguin is ready")
def whoisThis(self):
print("Penguin")
def run(self):
print("Run faster")
peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()
Результат работы программы:
Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster
Сначала мы создали два класса: Bird (родительский класс) и Penguin (дочерний класс). Он наследует функции родительского класса. Это прослеживается в методе swim().
Дочерний класс изменил поведение родительского класса – метод whoisThis(). Также мы расширяем родительский класс, создав новый метод run().
Мы используем функцию super() перед методом __init__(), чтобы извлечь содержимое метода __init__() из родительского класса в дочерний.
Инкапсуляция
Используя ООП в Python, мы можем ограничить доступ к методам и переменным. Это предотвращает изменение данных вне класса. Такой подход называется инкапсуляцией. В Python мы устанавливаем приватный модификатор доступа, используя в качестве префикса подчеркивание одинарное «_» или двойное «_ _» подчеркивание.
Пример 4: Инкапсуляция данных в Python
class Computer:
def __init__(self):
self.__maxprice = 900
def sell(self):
print("Selling Price: {}".format(self.__maxprice))
def setMaxPrice(self, price):
self.__maxprice = price
c = Computer()
c.sell()
# изменяем цену
c.__maxprice = 1000
c.sell()
# используем функцию сеттера
c.setMaxPrice(1000)
c.sell()
Когда мы запустим эту программу, результат будет следующим:
Selling Price: 900
Selling Price: 900
Selling Price: 1000
Сначала мы определили класс Computer . Затем использовали метод __init__() для хранения значения максимальной стоимости продажи компьютера.
Мы попытались изменить цену, но не смогли, потому что Python рассматривает __maxprice, как приватные атрибуты. Чтобы изменить значение, мы использовали функцию сеттера. То есть, setMaxPrice(), которая принимает цену в качестве параметра.
Полиморфизм
Полиморфизм - это способность использовать в ООП общий интерфейс для нескольких форм (типов данных).
Предположим, что нужно раскрасить фигуру. Есть несколько вариантов фигуры (прямоугольник, квадрат, круг). Мы могли бы использовать тот же метод, чтобы закрасить любую форму. Эта концепция называется полиморфизмом.
Пример 5: Использование полиморфизма в Python
class Parrot:
def fly(self):
print("Parrot can fly")
def swim(self):
print("Parrot can't swim")
class Penguin:
def fly(self):
print("Penguin can't fly")
def swim(self):
print("Penguin can swim")
# общий интерфейс
def flying_test(bird):
bird.fly()
#создаем объекты
blu = Parrot()
peggy = Penguin()
# передаем объекты
flying_test(blu)
flying_test(peggy)
Результат:
Parrot can fly
Penguin can't fly
Мы определили два класса: Parrot и Penguin . У каждого из них есть общий метод fly(), но они разные.
Чтобы реализовать полиморфизм, мы создали общий интерфейс. То есть, функцию flying_test(), которая может принимать любой объект. Затем мы передали объекты blu и peggy в функцию flying_test().
Преимущества использования ООП
- Программирование становится простым и эффективным.
- Класс общий, поэтому код можно использовать повторно.
- Производительность программистов увеличивается.
- Благодаря абстракции данные становятся безопасными и надежными.