I am a very amateur learner of Python, and I have recently started learning the concept of classes. I can understand the concept of classes (very) roughly, but I can't understand why I can't simply write some functions instead of writing a class?
For example, (I am learning from Interactive python) one of the exercise given (which I am supposed to write using a class) is :
Add a distanceFromPoint
method that works similar to distanceFromOrigin
except that it takes a Point
as a parameter and computes the distance between that point and self.
Add a method reflect_x
to Point
which returns a new Point
, one which is the reflection of the point about the x-axis. For example, Point(3, 5).reflect_x()
is (3, -5)
.
They written the code using classes like this:
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))
Why should I use class when I can write them simply like this:
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)
One of the big advantages of using OOP is extensibility.
Let's say you'd written an application that processes lots of data in the form of points. Now your customer adds to the specification that as well as the x and y coordinate of each point, your app needs to know what colour each point is.
If you'd written your code to store each point as a tuple, (x, y)
, you might add the colour as a third value: (x, y, colour)
. But now you have to go through all of your code to find the places where it's broken because you changed the data format. If you'd used a class, you could simply define a new class that inherits from Point
and adds the necessary capabilities:
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))
All your code that worked with the Point
class will still work with the new class, and you can do this even if you didn't write, or can't change, the definition of the Point
class.
You can declare a function outside of a class.
But storing them in class is a better pratice in general in programming. OOP is considered to be more readable and also reusable.
And in this case, the distance between two points depends on points, so it's logical to have the distanceFromPoint method in this class.
Class also allow you to be sure than you calculate the distance from Points and not for tuples who can contains bad values, like more than two coordinates.
Your example of a point is a bad one for justifying the use of classes.
A class is a great way of describing what something is rather than manipulating data. So a point just has two bits of information describing it (in 2D space anyway).
Think of something more abstract, like, a movie file. Movies have all sorts of information associated with them: title, duration, genres, actors, age rating, popularity, language, awards... goes on. Try writing functions that handle a long list of all of this information and you will quickly see the merits of a class.
Maths is maybe the one area where there really isn't that much contextual information, there are only a few variables and they define everything. Real-world data is less clearly defined and so benefits from the extensibility of classes.
Functional and object-oriented programming are different paradigms.
In Python, everything is an object, even int
s. The whole language goes towards object-oriented programming, which is why you should prefer going for it, especially if your program will grow.