Разбери основы на конкретном примере!

Наследование классов - важная концепция объектно-ориентированного программирования. Это позволяет нам расширить возможности существующего класса. Чтобы создать новый класс, мы используем доступный класс в качестве основы и расширяем его функциональность в соответствии с нашими потребностями. Поскольку мы создаем новый класс, используя методы и определения данных, доступные в базовом классе, время разработки и обслуживания сокращается, а возможность повторного использования кода увеличивается.

Этот пост познакомит вас с основами наследования классов в Python.

Если вы хотите изучить основы классов в Python, см. Мой предыдущий пост ниже;



Напишем код Python3, содержащий простой пример наследования классов;

import pandas as pd
import random
# BASE CLASS
class CSVGetInfo:
 """ This class displays the summary of the tabular data contained  
 in a CSV file """
 instance_count = 0
 # Initializer / Instance Attributes
 def __init__(self, path, file_name):
  CSVGetInfo.increase_instance_count()
  self.path = path
  self.file_name = file_name
  print("CSVGetInfo class object has been instantiated")
 # Instance Method
 def display_summary(self):
  data = pd.read_csv(self.path + self.file_name)
  print(self.file_name)
  print(data.head(self.generate_random_number(10)))
  print(data.info())
  return data
 # Class Methods
 @classmethod
 def increase_instance_count(cls):
  cls.instance_count += 1
  print(cls.instance_count)
 @classmethod
 def read_file_1(cls):
  return cls("/Users/erdemisbilen/Lessons/", "data_by_artists.csv")
 @classmethod
 def read_file_2(cls):
  return cls("/Users/erdemisbilen/Lessons/", "data_by_genres.csv")
 # Static Methods
 @staticmethod
 def generate_random_number(limit):
  return random.randint(1, limit)
# SUB CLASS
class CSVGetColumnDetails(CSVGetInfo):
 """ This class displays the summary of a column in a tabular data 
 contained in a CSV file """
 # Initializer / Instance Attributes
 def __init__(self, path, file_name, column_name):
  CSVGetInfo.__init__(self, path, file_name)
  self.column_name = column_name
  print("CSVGetDetail class object has been instantiated")
 # Instance Method
 def display_column_summary(self):
  data = self.display_summary()
  print(data[self.column_name].describe())
 @classmethod
 def read_file_1(cls, column_name):
  return cls("/Users/erdemisbilen/Lessons/", "data_by_artists.csv", 
  column_name)

if __name__ == '__main__':
 data = CSVGetColumnDetails.read_file_1("danceability")
 data.display_column_summary()

Наследование в Python

В нашем коде Python выше у нас есть базовый класс CSVGetInfo, который содержит несколько методов и определений данных.

Метод экземпляра display_summary (self) печатает сводку табличных данных, содержащихся в файле CVS, используя значения, указанные в пути и имя_файла.

Также существует несколько методов класса: read_file_1 (cls), read_file_2 (cls) и Increase_instance_count (cls) , чтобы упростить создание экземпляра объекта базового класса.

См. Мой предыдущий пост ниже для дальнейшего понимания типов методов (методы класса, методы экземпляра, статические методы) в Python;



Предположим, мы хотим создать новый класс CSVGetColumnDetails, чтобы получать сводную информацию о конкретном столбце в табличных данных. Мы можем написать новый класс с нуля, но лучший способ - унаследовать и расширить некоторые методы и определения данных, уже доступные в классе CSVGetInfo.

# BASE CLASS
class CSVGetInfo:
 ....
 ....
# SUB CLASS
class CSVGetColumnDetails(CSVGetInfo):
 ....
 ....

class SubClassName (BaseClassName) - это синтаксис наследования Python, используемый для создания подкласса. В нашем примере наш базовый класс - CSVGetInfo, а наш расширенный подкласс - CSVGetColumnDetails.

Инициализация атрибута в подклассе

Мы вызываем метод __init__ нашего базового класса, чтобы создать экземпляр path и file_name атрибуты. Мы наследуем эти атрибуты от нашего базового класса до нашего подкласса.

Атрибут column_name, который доступен только на уровне нашего подкласса, создается с нотацией self, представляющей CSVGetColumnDetails экземпляры .

# Initializer / Instance Attributes
 def __init__(self, path, file_name, column_name):
  CSVGetInfo.__init__(self, path, file_name)
  self.column_name = column_name
  print("CSVGetDetail class object has been instantiated")

Расширение методов, доступных в BaseClass

Затем мы создаем новый метод в нашем подклассе с помощью метода display_summary (), производного от базового класса. Мы используем и расширяем возможности display_summary () в нашем подклассе для определения нового метода.

# Instance Method
 def display_column_summary(self):
  data = self.display_summary()
  print(data[self.column_name].describe())

Этот новый метод в нашем подклассе display_column_summary (self), отображает сводку определенного столбца, используя данные display_summary (производные из базового класса) возвращается метод . Этот метод подкласса также имеет атрибут подкласса имя_столбца.

Переопределение методов, доступных в BaseClass

Обратите внимание, что у нас есть методы класса read_file_1, определенные как в нашем базовом, так и в подклассе с различными реализациями.

read_file_1 метод класса в базовом классе просто передает путь и имя_файла значения для создания экземпляров объектов базового класса, тогда как объект в подклассе создает экземпляры объектов подкласса с дополнительным аргументом column_name.

Это означает, что метод read_file_1 в подклассе переопределяет тот же метод, доступный в базовом классе. Когда эти методы вызываются, они выполняют свои уникальные реализации.

# BASE CLASS
class CSVGetInfo:
 ....
 ....
 @classmethod
 def read_file_1(cls):
  return cls("/Users/erdemisbilen/Lessons/", "data_by_artists.csv")
# SUB CLASS
class CSVGetColumnDetails(CSVGetInfo):
 ....
 ....
 @classmethod
 def read_file_1(cls, column_name):
  return cls("/Users/erdemisbilen/Lessons/", "data_by_artists.csv", 
  column_name)

Соглашения об именах при наследовании классов

В базовом классе могут быть некоторые методы или атрибуты (переменные экземпляра), которые предназначены для использования только в базовом классе. Они называются закрытыми методами и именуются с двойным подчеркиванием, __privatemethodname. Эти методы не следует вызывать вне базового класса, включая подклассы.

В базовом классе могут быть также некоторые другие методы или атрибуты, которые предназначены для использования только в определениях базового или подкласса. Они называются защищенными методами и именуются с использованием единого символа подчеркивания _protectedmethodname. Эти методы следует вызывать только в базовых структурах и структурах подкласса.

Основные выводы

  • Наследование увеличивает возможность повторного использования кода и сокращает время разработки и обслуживания.
  • Наследование позволяет нам определить класс, который принимает и расширяет все методы и определения данных, доступные в базовом классе.

Заключение

В этом посте я объяснил основы наследования классов в Python.

Код в этом посте и используемые файлы CSV доступны в моем репозитории GitHub.

Надеюсь, этот пост был вам полезен.

Спасибо за чтение!