Class.variable vs. object.variable

Hello,

I’m working on exercise 5 of the Python Code Challenges II section in the Learn Python 3 course. The code relevant to my question is pasted below.

class DriveBot:
  robot_count = 0

def __init__(self, motor_speed = 0, direction = 180, sensor_range = 10):
  DriveBot.robot_count += 1
  self.id = DriveBot.robot_count

robot_1 = DriveBot(5, 90, 10)
robot_2 = DriveBot(35, 75, 25)
robot_3 = DriveBot(20, 60, 10)

print(robot_1.id)
print(robot_2.id)
print(robot_3.id)

My question is, why does the first line in the constructor have to be DriveBot.robot_count += 1 ? When I write self.robot_count += 1 I get output of 0 0 0 vs the 1 2 3 that it should be. What’s the difference in writing it as class.variable vs. object.variable?

Also, when I keep it as written in the code block above but only change the second line to self.id = self.robot_count I get the right answer, 1 2 3 … How come this time they are interchangeable but in the aforementioned case, they are not?

Thanks in advance!

Link: https://www.codecademy.com/courses/learn-python-3/articles/python-code-challenges-classes

The above is polling the variable, and as there is no robot_count instance variable, self.robot_count is accessible even though it is a class variable. The same does not apply when setting the class variable. If we try to set it with self we end up creating another instance variable and have no reference to the class variable so cannot update it.

So if I’m understanding correctly, the reason why we cannot write self.robot_count += 1 is because that actually has no interaction with the class variable robot_count at all; it just creates a new instance variable…? And if this is the case, then you can have both a class variable and an instance variable by the same name, but with different values?

1 Like

Yes, and no. If it is direct assignment, yes; if augmented assignment it will raise an error. We cannot create an attribute with +=.

Once we define a self attribute, we shadow accessing the class variable with self since it now binds to the instance. That means two values exist. The class variable to all instances that have not overridden it will be accessible to read with self.variable, and that variable can be updated on the fly (by class name). All instances see the updated value.

There may be occasions where defining an instance variable to override the class can be useful, but the model would need to be well thought out and reasonable. Save this idea for later discussion. I’m sure it will be an interesting path down which to venture.

1 Like

Thank you for the consistent and diligent answers mtf!

1 Like