Methods that change the object
The values of an object's attributes at any moment are called its state. A method can change the state, and it's the usual way to do it. Here is a counter:
class Counter:
def __init__(self):
self.value = 0
def increase(self):
self.value += 1
def add(self, amount):
self.value += amount
def reset(self):
self.value = 0
clicks = Counter()
clicks.increase()
clicks.increase()
clicks.add(10)
print(clicks.value)
clicks.reset()
print(clicks.value)
12
0These methods don't return anything: their whole job is to change the object. They change the object that they are called on, and only that one:
class Counter:
def __init__(self):
self.value = 0
def increase(self):
self.value += 1
home = Counter()
away = Counter()
home.increase()
home.increase()
away.increase()
print(home.value, away.value)
2 1home.increase() runs the method with self as home, so self.value += 1 adds to the home counter. The away counter has a value of its own.
One call, every update
A method can update several attributes at once, so that they always fit together. A car that drives also uses fuel:
class Car:
def __init__(self, fuel, consumption):
self.fuel = fuel
self.consumption = consumption
self.odometer = 0
def drive(self, km):
self.odometer += km
self.fuel -= km * self.consumption / 100
def km_left(self):
return self.fuel / self.consumption * 100
car = Car(40, 5)
car.drive(120)
car.drive(80)
print(car.odometer, car.fuel)
print(car.km_left())
200 30.0
600.0(fuel is in liters and consumption in liters per 100 km.) The rest of the program only says car.drive(120). It doesn't need to know how the fuel is worked out, and it can't forget to update one of the attributes. This is the big idea of object-oriented programming: the class takes care of its own data.
A method can also change the state and return something, as the list method pop does: it removes an item and gives it to you.
Naming methods
Name a method after what it does. A method that changes the object usually gets a verb: increase, drive, reset. A method that only gives an answer is named after the answer, such as area or km_left, or it starts with is_ when the answer is yes or no: is_empty. Then the client code reads almost like a sentence: car.drive(120), if counter.is_empty():.