Язык программирования Python имеет все необходимые объекты и инструменты, позволяющие реализовать принципы объектно-ориентированного программирования. Основная конструкция, которая будет использоваться для этого – это класс.
Класс — это описание интересующих нас особенностей какой-то абстракции, на основе которого будут создаваться конкретные реализации этой абстракции.
Для создания класса используем ключевое слово class:
1class User: pass # этот класс ничего не делает
В отличие от переменных, для наименования которых в Python принято использовать snake_case, для классов используют CamelCase — регистр, в котором слова склеены между собой, и каждое начинается с заглавной буквы.
В Python экземпляры класса создаются следующим образом:
1bmw = Car()
2audi = Car()
При создании нового экземпляра класса в Python можно явным способом задать конструктор класса, с помощью метода __init__ , который заранее определяет атрибуты новых экземпляров. Первым аргументом он обязательно принимает на вход self, а дальше — произвольный набор аргументов. Этот метод вызывается каждый раз, когда мы создаём экземпляр.
1class Car:
2 def __init__(self, brand, model, reg_num):
3 self.brand = brand
4 self.model = model
5 self.reg_num = reg_num
Если вам доводилось разрабатывать на других языках программирования, то возможно вы рассчитываете на то, что Python предоставляет какие-то способы ограничить доступ одних объектов к другим и не предоставлять управления некоторыми атрибутами извне. Такие атрибуты обычно называют private.
В отличие от многих языков Python не даёт явной возможности принудительно закрыть доступ к каким-либо данным. Но при этом существует соглашение о том, что если название переменной начинается с двух нижних подчёркиваний, то она не предназначена для использования извне.
Для того чтобы реализовать принцип инкапсуляции, создаются отдельные методы получения и изменения реквизита экземпляра класса. В этих методах выполняется проверка всех необходимых условий, которым должен соответствовать атрибут, до его присвоения. В качестве примера рассмотрим методы получения и присвоения номера автомобиля экземпляру объекта.
1class Car:
2 _reg_num = None
3
4 def __init__(self, reg_num):
5 self._reg_num = reg_num # специальный метод для получения поля
6
7 @property
8 def reg_num(self):
9 return self._reg_num # специальный метод для установки нового значения
10
11 @reg_num.setter
12 def reg_num(self, reg_num):
13 if len(reg_num) == 8:
14 self._reg_num = reg_num
15
16c = Car('X999XX99')
17print(c.reg_num) # Вывод: X999XX99
18c.reg_num = 'A001AA99'
19print(c.reg_num) # Вывод: A001AA99
Теперь мы контролируем обращение к полям класса. Мы добавили специальные методы: геттеры и сеттеры.
Под наследованием понимается возможность использования дочерним классом родительских методов, свойств и другой логики. Наследование в python реализуется с помощью конструкции ниже.
1class Car:
2 _reg_num = None
3
4 def __init__(self, reg_num):
5 self._reg_num = reg_num # специальный метод для получения поля
6
7 @property
8 def reg_num(self):
9 return self._reg_num
10
11class ElectroCarFood(Car):
12 battery_type = ‘Pb’
Данная конструкция создает основной класс автомобиля, а также дочерний класс электромобиля, который наследует свойства и методы родительского класса, а также добавляет свои свойства электромобилю.
Также дополнительно отметим возможность определения статических методов в классе, т.е. методов, которые можно вызвать, не создавая экземпляр класса.
1class StaticClass:
2 @staticmethod # помечаем метод который мы хотим сделать статичным декоратором @staticmethod
3 def say_hello():
4 print("hello")
5
6StaticClass.say_hello()
На этом заканчиваем описание способов реализации принципов объектно-ориенторованного программирования на python.