Почему я должен использовать классы в python?

Я очень любительский ученик Python, и недавно я начал изучать концепцию классов. Я понимаю концепцию классов (очень) грубо, но я не могу понять, почему я не могу просто написать некоторые функции вместо написания класса?

Например, (я изучаю из Interactive python) одно из заданий (которое я должен писать с помощью класса)

  • Добавьте метод distanceFromPoint, который работает аналогично distanceFromOrigin, за исключением того, что он принимает Point в качестве параметра и вычисляет расстояние между этой точкой и я.

  • Добавьте метод reflect_x в Point, который возвращает новый Point, который является отражением точки относительно оси x. Например, Point(3, 5).reflect_x() - (3, -5).

Они написали код, используя следующие классы:

import math

class Point:
    """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):
    """ Create a new point at the given coordinates. """
    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

def distanceFromPoint(self, otherP):
    dx = (otherP.getX() - self.x)
    dy = (otherP.getY() - self.y)
    return math.sqrt(dy**2 + dx**2)

p = Point(3, 3)
q = Point(6, 7)

print(p.distanceFromPoint(q))

Почему я должен использовать класс, когда могу писать их просто так:

def distanceFromPoint(p,q): # they are tuples
    y = (p[0]-q[0])**(2)+(p[1]-q[1])**(2)
    return y**(1/2)

def reflectx(p):
    return (p[0],-p[1])

p = (3,3)
q = (6,7)

Ответ 1

Одним из больших преимуществ использования ООП является расширяемость.

Скажем, вы написали приложение, которое обрабатывает множество данных в виде точек. Теперь ваш клиент добавляет к спецификации, а также координату x и y каждой точки, ваше приложение должно знать, какой цвет имеет каждая точка.

Если вы написали свой код для хранения каждой точки в качестве кортежа, (x, y), вы можете добавить цвет в качестве третьего значения: (x, y, colour). Но теперь вам нужно пройти весь свой код, чтобы найти места, где он сломан, потому что вы изменили формат данных. Если бы вы использовали класс, вы могли бы просто определить новый класс, который наследует от Point, и добавляет необходимые возможности:

class ColouredPoint(Point):
    """ Class for points which are coloured, based on Point """

    def __init__(self, initX, initY, initCol):
        Point.__init__(self, initX, initY)
        self.colour = initCol

p = ColouredPoint(3, 3, "green")
q = ColouredPoint(6, 7, "red")
r = Point(8, 4)

print(p.distanceFromPoint(q))
print(p.colour)
print(p.distanceFromPoint(r))

Весь ваш код, который работал с классом Point, по-прежнему будет работать с новым классом, и вы можете это сделать, даже если вы не указали или не смогли изменить определение класса Point.

Ответ 2

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

И в этом случае расстояние между двумя точками зависит от точек, поэтому логично иметь метод distanceFromPoint в этом классе.

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

Ответ 3

Ваш пример точки является плохим для обоснования использования классов.

Класс - отличный способ описать что-то, а не манипулировать данными. Таким образом, точка имеет только два бита информации, описывающих его (в любом случае в 2D-пространстве).

Подумайте о чем-то более абстрактном, например, файле фильма. У фильмов есть вся информация, связанная с ними: название, продолжительность, жанры, актеры, возрастный рейтинг, популярность, язык, награды... продолжается. Попробуйте написать функции, которые обрабатывают длинный список всей этой информации, и вы быстро увидите достоинства класса.

Maths - это, возможно, одна область, где действительно не так много контекстной информации, есть только несколько переменных, и они определяют все. Реальные данные менее четко определены и, следовательно, извлекают выгоду из расширяемости классов.

Ответ 4

Functional и object-oriented программирование различные парадигмы.

В Python все это объект, даже int s. Весь язык идет в сторону объектно-ориентированного программирования, поэтому вы должны предпочесть его, особенно если ваша программа будет расти.