Классы в Python
Объектно-ориентированное программирование считается одним из самых эффективных методов создания программ. В объектно-ориентированном программирование создаются классы, описывающие реальные предметы и ситуации, а затем создаете объекты на основе этих описаний. Созданием объекта на основе класса называется созданием экземпляра.
Содержание страницы: |
---|
1. Создание класса |
1.1. Метод __init__() |
1.2. Создание экземпляра класса |
1.3. Обращение к атрибутам класса |
1.4. Вызов методов класса |
2. Работа с классами |
2.1. Прямое изменение значения атрибута |
2.2. Изменение значения атрибута с использованием метода |
2.3. Изменение значения атрибута с приращением |
3. Наследование класса |
3.1. Переопределение методов класса-родителя |
1. Создание класса в Python
Классы в Python могут моделировать практически все что угодно. Создадим простой класс, который будет описывать конкретный автомобиль:
class Car():
"""Описание автомобиля"""
def __init__(self, brand, model):
"""Инициализирует атрибуты brand и model"""
self.brand = brand
self.model = model
def sold(self):
"""Автомобиль продан"""
print(f"Автомобиль {self.brand} {self.model} продан ")
def discount(self):
"""Скидка на автомобиль"""
print(f"На автомобиль {self.brand} {self.model} скидка 5%")
Разберем код по порядку. В начале определяется класс с именем Car (class Car). По общепринятым соглашение название класса начинается с символа верхнего регистра. Круглые скобки в определение класса пусты, так как класс создается с нуля. Далее идет строка документации с кратким описанием. ("""Описание автомобиля""").
1.1. Метод __init__()
Функция, являющаяся частью класса, называется методом. Все свойства функций так же относятся и к методам, единственное отличие это способ вызова метода. Метод __init__() - специальный метод, который автоматически выполняется при создание нового экземпляра. Имя метода начинается и заканчивается двумя символами подчеркивания. Метод __init__() определяется с тремя параметрами: self, brand, model. Параметр self обязателен в определение метода и должен стоять перед всеми остальными параметрами. При создании экземпляра на основе класса Car, необходимо передать только два последних аргумента brand и model.
Каждая из двух переменных self.brand = brand и self.model = model снабжена префиксом self и к ним можно обращаться вызовом self.brand и self.model. Значения берутся из параметров brand и model. Переменные, к которым вы обращаетесь через экземпляры, также называются атрибутами.
В классе Car также есть два метода: sold() и discount(). Этим методам не нужна дополнительная информация и они определяются с единственным параметром self. Экземпляры, которые будут созданы на базе этого класса смогут вызывать данные методы, которые просто выводят информацию.
1.2. Создание экземпляра класса
С помощью класса Car мы можем создавать экземпляры для конкретного автомобиля. Каждый экземпляр описывает конкретный автомобиль и его параметры.
car_1 = Car('Bmw', 'X5')
Создадим переменную car_1 и присвоим ей класс с параметрами автомобиля которые нужно обязательно передать (brand, model). При выполнение данного кода Python вызывает метод __init__ , создавая экземпляр, описывающий конкретный автомобиль и присваивает атрибутам brand и model переданные значения. Этот экземпляр сохраняется в переменной car_1.
1.3. Обращение к атрибутам класса
К атрибутам экземпляра класса мы можем обращаться через запись:
print(f"{car_1.brand}")
print(f"{car_1.model}")
В записи используется имя экземпляра класса и после точки имя атрибута (car_1.brand) или (car_1.model). В итоге на экран выведется следующая информация:
Bmw
X5
1.4. Вызов методов класса
После создания экземпляра на основе класса Car можете вызывать любые методы, написанные в классе. Чтобы вызвать метод, укажите экземпляр (car_1) и вызываемый метод после точки:
car_1.sold()
car_1.discount()
При вызове данных методов, Python выполнит код, написанный в этом методе.
Автомобиль Bmw X5 продан
На автомобиль Bmw X5 скидка 5%
2. Работа с классами на Python
Большая часть времени работы программиста - это работа с классами и их экземплярами. Изменим наш предыдущий класс Car и добавим дополнительные атрибуты, которые сможем в последующем менять при работе с экземплярами класса.
class Car():
"""Описание автомобиля"""
def __init__(self, brand, model, years):
"""Инициализирует атрибуты"""
self.brand = brand
self.model = model
self.years = years
self.mileage = 0
def get_full_name(self):
"""Автомобиль"""
name = f"Автомобиль {self.brand} {self.model} {self.years}"
return name.title()
def read_mileage(self):
"""Пробег автомобиля"""
print(f"Пробег автомобиля {self.mileage} км.")
В описание автомобиля есть три атрибута(параметра) это brand, model, years. Также мы создали новый атрибут mileage (пробег) и присвоили ему начальное значение 0. Так как пробег у всех автомобилей разный, в последующем мы сможем изменять этот атрибут. Метод get_full_name будет возвращать полное описание автомобиля. Метод read_mileage будет выводить пробег автомобиля.
Создадим экземпляр с классом Car и запустим методы:
car_2 = Car('audi', 'a4', 2019)
print(car_2.get_full_name())
car_2.read_mileage()
В результате в начале Python вызывает метот __init__() для создания нового экземпляра. Сохраняет название, модель, год выпуска и создает новый атрибут с пробегом равным 0. В итоге мы получим такой результат:
Автомобиль Audi A4 2019
Пробег автомобиля 0 км.
2.1. Прямое изменение значения атрибута
Для изменения значения атрибута можно обратиться к нему напрямую и присвоить ему новое значение. Изменим пробег автомобиля car_2:
car_2 = Car('audi', 'a4', 2019)
print(car_2.get_full_name())
car_2.mileage = 38
car_2.read_mileage()
Мы обратились к нашему экземпляру car_2 и связанным с ним атрибутом пробега(mileage) и присвоили новое значение 38. Затем вызвали метод read_mileage() для проверки. В результате мы получим следующие данные.
Автомобиль Audi A4 2019
Пробег автомобиля 38 км.
2.2. Изменение значения атрибута с использованием метода
В Python удобнее писать методы, которые будут изменять атрибуты за вас. Для этого вы просто передаете новое значение методу, который обновит значения. Добавим в наш класс Car метод update_mileage() который будет изменять показания пробега.
class Car():
"""Описание автомобиля"""
def __init__(self, brand, model, years):
"""Инициализирует атрибуты"""
self.brand = brand
self.model = model
self.years = years
self.mileage = 0
def get_full_name(self):
"""Автомобиль"""
name = f"Автомобиль {self.brand} {self.model} {self.years}"
return name.title()
def read_mileage(self):
"""Пробег автомобиля"""
print(f"Пробег автомобиля {self.mileage} км.")
def update_mileage(self, new_mileage):
"""Устанавливает новое значение пробега"""
self.mileage = new_mileage
car_2 = Car('audi', 'a4', 2019)
print(car_2.get_full_name())
car_2.read_mileage()
car_2.update_mileage(17100)
car_2.read_mileage()
Вначале выведем текущие показания пробега ( car_2.read_mileage() ). Затем вызовем метод update_mileage() и передадим ему новое значение пробега ( car_2.update_mileage(17100) ). Этот метод устанавливает пробег 17100. Выведем текущие показания ( car_2.read_mileage() ) и у нас получается:
Автомобиль Audi A4 2019
Пробег автомобиля 0 км.
Пробег автомобиля 17100 км.
2.3. Изменение значения атрибута с приращением
Если вместо того, чтобы присвоить новое значение, требуется изменить с значение с приращением, то в этом случаем мы можем написать еще один метод, который будет просто прибавлять пробег к уже имеющемся показаниям. Для этого добавим метод add_mileage в класс Car:
def add_mileage(self, km):
"""Добавляет пробег"""
self.mileage += km
Новый метод add_mileage() получает пробег в км и добавлет его к self.mileage.
car_2.add_mileage(14687)
car_2.read_mileage()
Пробег автомобиля 31787 км.
В итоге после вызова метода add_mileage() пробег автомобиля в экземпляре car_2 увеличится на 14687 км и станет равным 31787 км. Данный метод мы можем вызывать каждый раз при изменении пробега и передавать новые значение, на которое будет увеличивать основной пробег.
3. Наследование класса в Python
Создавая новые классы не обязательно их создавать с нуля. Новый класс может наследовать свои атрибуты (переменные) и методы (функции принадлежащие классам) от ранее определенного исходного класса ( суперкласса ). Также исходный класс называют родителем, а новый класс - потомком или подклассом. В класс-потомок можно добавлять собственные атрибуты и методы. Напишем новый класс ElectricCar, который будет создан на базе класса Car:
class Car():
"""Описание автомобиля"""
def __init__(self, brand, model, years):
"""Инициализирует атрибуты brand и model"""
self.brand = brand
self.model = model
self.years = years
self.mileage = 0
def get_full_name(self):
"""Автомобиль"""
name = f"Автомобиль {self.brand} {self.model} {self.years}"
return name.title()
def read_mileage(self):
"""Пробег автомобиля"""
print(f"Пробег автомобиля {self.mileage} км.")
def update_mileage(self, new_mileage):
"""Устанавливает новое значение пробега"""
self.mileage = new_mileage
def add_mileage(self, km):
"""Добавляет пробег"""
self.mileage += km
class ElectricCar(Car):
"""Описывает электромобиль"""
def __init__(self, brand, model, years):
"""Инициализирует атрибуты класса родителя"""
super().__init__(brand, model, years)
# атрибут класса-потомка
self.battery_size = 100
def battery_power(self):
"""Выводит мощность аккумулятора авто"""
print(f"Мощность аккумулятора {self.battery_size} кВт⋅ч")
Мы создали класс ElectriCar на базе класса Car. Имя класса-родителя в этом случае ставится в круглые скобки( class ElectricCar(Car) ). Метод __init__ в классе потомка (подклассе) инициализирует атрибуты класса-родителя и создает экземпляр класса Car. Функция super() .- специальная функция, которая приказывает Python вызвать метод __init__() родительского класса Car, в результате чего экземпляр ElectricCar получает доступ ко всем атрибутам класса-родителя. Имя super как раз и происходит из-за того, что класс-родителя называют суперклассом, а класс-потомок - подклассом.
Далее мы добавили новый атрибут self.battery_size и присвоили исходное значение 100. Этот атрибут будет присутствовать во всех экземплярах класса ElectriCar. Добавим новый метод battery_power(), который будет выводить информацию о мощности аккумулятора.
Создадим экземпляр класса ElectriCar и сохраним его в переменную tesla_1
tesla_1 = ElectricCar('tesla', 'model x', 2021)
print(tesla_1.get_full_name())
tesla_1.battery_power()
При вызове двух методов мы получим:
Автомобиль Tesla Model X 2021
Мощность аккумулятора 100 кВт⋅ч
В новый класс ElectriCar мы можем добавлять любое количество атрибутов и методов связанных и не связанных с классом-родителем Car.
3.1. Переопределение методов класса-родителя
Методы, которые используются в родительском классе можно переопределить в классе-потомке (подклассе). Для этого в классе-потомке определяется метод с тем же именем, что и у класса-родителя. Python игнорирует метод родителя и переходит на метод, написанный в классе-потомке (подклассе). Переопределим метод def get_full_name() чтобы сразу выводилась мощность аккумуляторов.
class ElectricCar(Car):
"""Описывает электромобиль"""
def __init__(self, brand, model, years):
"""Инициализирует атрибуты класса родителя"""
super().__init__(brand, model, years)
# атрибут класса-потомка
self.battery_size = 100
def battery_power(self):
"""Выводит мощность аккумулятора авто"""
print(f"Мощность аккумулятора {self.battery_size} кВт⋅ч")
def get_full_name(self):
"""Автомобиль"""
name = f"Автомобиль {self.brand} {self.model} {self.years} {self.battery_size}-кВт⋅ч "
return name.title()
В результате при запросе полного названия автомобиля Python проигнорирует метод def get_full_name() в классе-родителя Car и сразу перейдет к методу def get_full_name() написанный в классе ElectricCar.
tesla_1 = ElectricCar('tesla', 'model x', 2021)
print(tesla_1.get_full_name())
Автомобиль Tesla Model X 2021 100-Квт⋅Ч
Далее: Файлы и исключения в Python