Explore Class Attribute Quirks
00:00 I want to know what type of animal each animal is, and I want to keep track of that inside of the class. This sounds like a good idea to use a class attribute for it because all dogs are going to be dogs, right?
So one way that you could go is just define the class attribute in here. I’m going to say
.animal_type and say that every instance of this
Dog class is going to have the
"dog" and do the same for
Sheep, only those are going to be pigs and sheep.
So I’m going to do something maybe controversial, I’m not sure, but I actually want to show you something about that. I’m going to add an
None to the parent class because I want to show you something about the attribute lookup order that might be a little tricky when you’re working with class attributes.
That looks good. But what is interesting here is that if you change, maybe accidentally, or I don’t know why you would do it intentionally, but it could happen that you say
d.animal_type equals something else. Let’s say this is a
This doesn’t change the class attribute. The class attribute is still
"dog" also for this
Dog, but because of the attribute lookup order in Python, it means that now if you look for
d.animal_type in the same way that it did before, you’re going to get
"fox" back because you created a new instance attribute of
.animal_type that shadows the class attribute
So this can be a little bit confusing right now you have
d.animal_type pointing to
"fox", and you do still have access to the class attribute as well, but you have to access it using
And there you can see that this is still a
"dog". However, if you write some code that works with the class attribute, but accessing it from the instance, then you might accidentally override it and kind of run into trouble there.
I think it makes sense for this design. I want to have a class attribute on
Dog that just points to
"dog", and every
Dog instance should be a
"dog". So I’m pretty happy with this design, but just keep in mind that there’s this attribute lookup order that first looks at the instance and then looks at the first class and then goes upwards looking at all the parent classes.
This is why here you get when you type
d.animal_type, after assigning it to
"fox", you’re going to get
"fox" instead of earlier getting
"dog", because it finds it in the instance already after you’ve created this
.animal_type instance attribute. And then it doesn’t look for the class attribute anymore.
03:57 Long story short, this is a subjective design decision now and comes with some gotchas, but in this case, it also comes with some benefits. I like the idea of having the class attribute defining what type of animal this is. So I’m going to keep it like that.
Become a Member to join the conversation.