Instance attributes are specific to an object, while class attributes are shared across all objects created from the same class. Inside the class, the instance attributes are assigned and accessed using dot notation on the
self reference, while class attributes are referenced directly on the class.
Inside the class declaration block when I create an attribute this way, it’s a class attribute. That means it’ll be common across all object instances constructed from this class. Remember, to get at an instance inside the class, you need
self, and there’s no
self here, so it’s on the class instead.
Each time you create a new object,
.__init__() gets called. So this is a good place to increment the counter that counts how many instances there are. To access the class attribute, I use the name of the class instead of
self, and then here I’m incrementing its value by one.
and there it is. That ugly bit of REPL response is because I haven’t defined how to represent this object. The default display shows the name of the class, the module it’s in (
__main__), and a reference address.
03:08 You’ve seen class attributes can be accessed through the object, and you saw that the class attribute is modified through the class, but it’s important to note that it can only be modified through the class.
03:32 Python also supports overriding values. When you assign an attribute on an object, Python sees this as being an object attribute. If you already have a class attribute with the same name, it gets overridden, hence the subtle bug.
as a reminder, that’s the preferred way: doing it on the class itself. I mentioned I can assign attributes on objects dynamically. Here, I’ve added a new one called
.value, and it’s an attribute just like anything else.
Here, I’ve done the exact same thing. I’ve created a
.num_instances attribute and added a value dynamically. Since it has the same name as the class attribute, the object’s attribute takes precedence. So the class attribute hasn’t changed,
but the object attribute is
85. This would be why I prefer to use the class name. It’s clearer and avoids this problem. If you don’t have the class handy (say it’s declared in another file), you can get at an object’s class through the
05:29 And as that’s the object’s class, you can get at its attributes from there. See? Although Python doesn’t stop you from accessing class attributes from the object, it’s a good habit to strictly access them from the class itself to avoid confusion. If you’re coming to Python from a strictly typed compiled object-oriented language, I suspect you’re thinking this is a giant foot gun.
06:05 The other side of that coin, though, is some truly powerful things can be done with the dynamic nature of Python. A lot of the magic behind SQLAlchemy and Django’s ORM and how they map to databases is built on top of the dynamic nature of Python, so you gain some power at the risk of certain kinds of bugs.
Become a Member to join the conversation.