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.
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)
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!
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?
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.
Thank you for the consistent and diligent answers mtf!