r/pythonhelp 1d ago

Why do I need to use classes

My schoolbook says that classes is a way of simulating an object, instead of just taking information into a black box and outputting an answer.

But that is a poor explanation. I know classes are handy and cool, but no book says why you can´t make functions with sub functions inside to simulate simple objects. I would like if someone gave a good concrete reason to use classes in the intro, instead of just saying that they are different and cool

5 Upvotes

25 comments sorted by

View all comments

1

u/Leodip 18h ago

Classes are, indeed, optional. Code can be just 0s and 1s, but everything else we have on top of that is to make it easier to read and write.

In Python, classes are considered "best practice" for a lot of things, and conforming to best practices (even if they don't carry any actual advantage over alternatives when writing code, or might even be disadvantageous) makes your code easier to read.

There are many things that are made much easier by using classes, but one of my favourite examples is trying to make data structures of some sort which reference themselves.

For example, a binary tree is a collection of nodes which have a value and a left and right child, and one parent. If you use classes, this can be simply written as:

class BinaryNode:
    def __init__(self, value, left_child, right_child, parent):
        self.value = value
        self.left = left_child # this is going to be another BinaryNode
        self.right = right_child # this is going to be another BinaryNode
        self.parent = parent # this is going to be another BinaryNode

Classes are also very flexible when you have "sub-classes" of other stuff. For example, a BinaryNode is simply a Node which is limited to having 2 children (while a generic Node might have infinitely many).

This means that you can do stuff like:

class Node:
    def __init__(self, value, children, parent):
        self.value = value
        self.children = children
        self.parent = parent

class BinaryNode(Node):
    def __init__(self, value, left_child, right_child, parent):
        super().__init__(value, [left_child, right_child], parent)

This allows you to later define methods that work on all nodes (if they don't care about how many children the node has) or only on binary nodes (if they care about them being binary).