This question truly is too broad to get a complete answer, so let me give you one that fits the scope of your example, rather than the scope of your question.
As a few commenters have noticed, you use classes to give your functions a stateful environment to run in. Imagine I wanted to create a counter, for instance. I could use a global variable and a function, like:
counter = 0
def increment_counter():
global counter
counter += 1
def decrement_counter():
global counter
counter -= 1
but this pollutes our namespace with two extra function signatures and a variable. Plus the global
keyword is a code smell that should be avoided when possible. Not to mention you can only have one such counter in your whole code base! If you needed another, you'd have to retype all that code and violate DRY (Don't Repeat Yourself).
Instead we create a class:
class Counter(object):
def __init__(self):
self.count = 0
# initialize count at zero
def increment(self, by=1):
self.count += by
def decrement(self, by=1):
self.count -= by
Now you can instantiate that as many times as you'd like, and each one keeps track of its own separate count, e.g.:
counter_a = Counter()
counter_b = Counter()
for _ in range(3):
counter_a.increment()
for _ in range(1000000):
counter_b.increment()
assert counter_a.count == 3
assert counter_b.count == 1000000