Ответ 1
Классы - это столп объектно-ориентированное программирование. ООП очень озабочен организацией кода, возможностью повторного использования и инкапсулированием.
Во-первых, отказ от ответственности: ООП частично противоречит "Функциональное программирование" , которое представляет собой другую парадигму, используемую в Python. Не все, кто программирует на Python (или, конечно же, большинство языков), используют OOP. Вы можете многое сделать в Java 8, который не очень объектно ориентирован. Если вы не хотите использовать ООП, не делайте этого. Если вы просто пишете одноразовые скрипты для обработки данных, которые больше никогда не будете использовать, продолжайте писать так, как вы.
Однако существует много причин использовать ООП.
Некоторые причины:
-
Организация: ООП определяет хорошо известные и стандартные способы описания и определения как данных, так и процедуры в коде. Как данные, так и процедура могут храниться на разных уровнях определения (в разных классах), и есть стандартные способы говорить об этих определениях. То есть, если вы используете ООП стандартным образом, это поможет вашему более позднему я и другим понять, отредактировать и использовать ваш код. Кроме того, вместо использования сложного, произвольного механизма хранения данных (dicts dicts или списков или dicts или списков dicts наборов или что-то еще) вы можете называть части структур данных и удобно ссылаться на них.
-
Состояние: ООП помогает вам определять и отслеживать состояние. Например, в классическом примере, если вы создаете программу, которая обрабатывает студентов (например, программу оценки), вы можете хранить всю необходимую информацию о них в одном месте (имя, возраст, пол, уровень оценки, курсы, классы, учителя, сверстники, диеты, особые потребности и т.д.), и эти данные сохраняются до тех пор, пока объект жив, и легко доступны.
-
Encapsulation: При инкапсуляции процедура и данные сохраняются вместе. Методы (термин ООП для функций) определяются непосредственно рядом с данными, которые они работают и производят. На языке, подобном Java, который позволяет контроль доступа или на Python, в зависимости от того, как вы описываете свой публичный API, это означает, что методы и данные могут быть скрыты от пользователя. Это означает, что если вам нужно или хотите изменить код, вы можете делать все, что хотите для реализации кода, но сохраняйте общедоступные API-интерфейсы одинаковыми.
-
Inheritance: Наследование позволяет определить данные и процедуру в одном месте (в одном классе), а затем переопределить или расширить эту функциональность позже. Например, в Python я часто вижу, как люди создают подклассы класса
dict
, чтобы добавить дополнительные функции. Общее изменение переопределяет метод, который генерирует исключение, когда запрашивается ключ из словаря, который не существует, чтобы дать значение по умолчанию на основе неизвестного ключа. Это позволяет вам расширить свой собственный код сейчас или позже, позволить другим расширять ваш код и позволяет расширять код других людей. -
Повторяемость: все эти причины и другие возможности позволяют увеличить повторное использование кода. Объектно-ориентированный код позволяет вам писать твердый (проверенный) код один раз, а затем повторно использовать снова и снова. Если вам нужно настроить что-то для вашего конкретного случая использования, вы можете наследовать от существующего класса и перезаписать существующее поведение. Если вам нужно что-то изменить, вы можете изменить все это, сохранив существующие публичные сигнатуры методов, и никто не станет более мудрым (надеюсь).
Опять же, есть несколько причин не использовать ООП, и вам не нужно. Но, к счастью, с языком, подобным Python, вы можете использовать его немного или много, это зависит от вас.
Пример примера использования студента (нет гарантии качества кода, всего лишь пример):
Объектно-ориентированный
class Student(object):
def __init__(self, name, age, gender, level, grades=None):
self.name = name
self.age = age
self.gender = gender
self.level = level
self.grades = grades or {}
def setGrade(self, course, grade):
self.grades[course] = grade
def getGrade(self, course):
return self.grades[course]
def getGPA(self):
return sum(self.grades.values())/len(self.grades)
# Define some students
john = Student("John", 12, "male", 6, {"math":3.3})
jane = Student("Jane", 12, "female", 6, {"math":3.5})
# Now we can get to the grades easily
print(john.getGPA())
print(jane.getGPA())
Стандартный Dict
def calculateGPA(gradeDict):
return sum(gradeDict.values())/len(gradeDict)
students = {}
# We can set the keys to variables so we might minimize typos
name, age, gender, level, grades = "name", "age", "gender", "level", "grades"
john, jane = "john", "jane"
math = "math"
students[john] = {}
students[john][age] = 12
students[john][gender] = "male"
students[john][level] = 6
students[john][grades] = {math:3.3}
students[jane] = {}
students[jane][age] = 12
students[jane][gender] = "female"
students[jane][level] = 6
students[jane][grades] = {math:3.5}
# At this point, we need to remember who the students are and where the grades are stored. Not a huge deal, but avoided by OOP.
print(calculateGPA(students[john][grades]))
print(calculateGPA(students[jane][grades]))