I was asked to implement a certain API, and chose to do so in Python. Abstracting away the problem statement, let’s say I needed a class whose instances stored some
1
<td>
<div class="text codecolorer">
data
</div>
</td>
</tr>
As it turns out, we were both wrong. The real answer lay in understanding the distinction between Python class attributes and Python instance attributes.
<p class="is-centered">
<img src="https://i2.wp.com/uploads.toptal.io/blog/image/302/toptal-blog-image-1392824783170.png?w=688&ssl=1" alt="Python class attributes vs. Python instance attributes" data-recalc-dims="1" />
</p>
_Note: if you have an expert handle on class attributes, you can skip ahead to [use cases][4]._
## Python Class Attributes {#python-class-attributes}
My interviewer was wrong in that the above code _is_ syntactically valid.
I too was wrong in that it isn’t setting a “default value” for the instance attribute. Instead, it’s defining
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
data
</div>
</td>
</tr>
</table>
</div>
as a _class_ attribute with value
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
[]
</div>
</td>
</tr>
</table>
</div>
.
In my experience, Python class attributes are a topic that _many_ people know _something_ about, but few understand completely.
### Python Class Variable vs. Instance Variable: What’s the Difference? {#python-class-variable-vs-instance-variable-whats-the-difference}
A Python class attribute is an attribute of the class (circular, I know), rather than an attribute of an _instance_ of a class.
Let’s use a Python class example to illustrate the difference. Here,
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
class_var
</div>
</td>
</tr>
</table>
</div>
is a class attribute, and
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
i_var
</div>
</td>
</tr>
</table>
</div>
is an instance attribute:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
Note that all instances of the class have access to
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
class_var
</div>
</td>
</tr>
</table>
</div>
, and that it can also be accessed as a property of the _class itself_:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
For Java or C++ programmers, the class attribute is similar—but not identical—to the static member. We’ll see how they differ later.
### Class vs. Instance Namespaces {#class-vs-instance-namespaces}
To understand what’s happening here, let’s talk briefly about **Python namespaces**.
A <a href="http://docs.python.org/2/tutorial/classes.html" target="_blank" rel="noopener noreferrer">namespace</a> is a mapping from names to objects, with the property that there is zero relation between names in different namespaces. They’re usually implemented as Python dictionaries, although this is abstracted away.
Depending on the context, you may need to access a namespace using dot syntax (e.g.,
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
object.name_from_objects_namespace
</div>
</td>
</tr>
</table>
</div>
) or as a local variable (e.g.,
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
object_from_namespace
</div>
</td>
</tr>
</table>
</div>
). As a concrete example:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
1 2 3 4 5 6 7 8 9 10
<td>
<div class="text codecolorer">
class MyClass(object):<br />
## No need for dot syntax<br />
class_var = 1<br />
<br />
def __init__(self, i_var):<br />
self.i_var = i_var<br />
<br />
## Need dot syntax as we've left scope of class namespace<br />
MyClass.class_var<br />
## 1
</div>
</td>
</tr>
Python classes _and_ instances of classes each have their own distinct namespaces represented by <a href="http://www2.lib.uchicago.edu/keith/courses/python/class/5/##classinst" target="_blank" rel="noopener noreferrer">pre-defined attributes</a>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
MyClass.__dict__
</div>
</td>
</tr>
</table>
</div>
and
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
</div>
</td>
</tr>
</table>
</div>
, respectively.
When you try to access an attribute from an instance of a class, it first looks at its _instance_ namespace. If it finds the attribute, it returns the associated value. If not, it _then_ looks in the _class_ namespace and returns the attribute (if it’s present, throwing an error otherwise). For example:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
1 2 3 4 5 6 7 8 9 10
<td>
<div class="text codecolorer">
foo = MyClass(2)<br />
<br />
## Finds i_var in foo's instance namespace<br />
foo.i_var<br />
## 2<br />
<br />
## Doesn't find class_var in instance namespace…<br />
## So look's in class namespace (MyClass.__dict__)<br />
foo.class_var<br />
## 1
</div>
</td>
</tr>
The instance namespace takes supremacy over the class namespace: if there is an attribute with the same name in both, the instance namespace will be checked first and its value returned. Here’s a simplified version of the code (<a href="http://www2.lib.uchicago.edu/keith/courses/python/class/5/##classinst" target="_blank" rel="noopener noreferrer">source</a>) for attribute lookup:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
And, in visual form:
<p class="is-centered">
<img src="https://i0.wp.com/uploads.toptal.io/blog/image/301/toptal-blog-image-1392824596580.png?w=688&ssl=1" alt="attribute lookup in visual form" data-recalc-dims="1" />
</p>
### How Class Attributes Handle Assignment {#how-class-attributes-handle-assignment}
With this in mind, we can make sense of how Python class attributes handle assignment:
* If a class attribute is set by accessing the class, it will override the value for _all_ instances. For example:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
_At the namespace level…_ we’re setting
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
MyClass.__dict__['class_var'] = 2
</div>
</td>
</tr>
</table>
</div>
. (Note: this <a href="http://stackoverflow.com/questions/432786/how-can-i-assign-a-new-class-attribute-via-dict-in-python" target="_blank" rel="noopener noreferrer">isn’t the exact code</a>(which would be
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
setattr(MyClass, 'class_var', 2)
</div>
</td>
</tr>
</table>
</div>
) as
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
__dict__
</div>
</td>
</tr>
</table>
</div>
returns a <a href="http://me.veekun.com/blog/2013/08/05/dictproxyhack-or-activestate-code-considered-harmful/##dictproxy" target="_blank" rel="noopener noreferrer">dictproxy</a>, an immutable wrapper that prevents direct assignment, but it helps for demonstration’s sake). Then, when we access
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
foo.class_var
</div>
</td>
</tr>
</table>
</div>
,
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
class_var
</div>
</td>
</tr>
</table>
</div>
has a new value in the class namespace and thus 2 is returned.</li>
* If a Paython class variable is set by accessing an instance, it will override the value _only for that instance_. This essentially overrides the class variable and turns it into an instance variable available, intuitively, _only for that instance_. For example:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
_At the namespace level…_ we’re adding the
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
class_var
</div>
</td>
</tr>
</table>
</div>
attribute to
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
foo.__dict__
</div>
</td>
</tr>
</table>
</div>
, so when we lookup
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
foo.class_var
</div>
</td>
</tr>
</table>
</div>
, we return 2. Meanwhile, other instances of
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
MyClass
</div>
</td>
</tr>
</table>
</div>
will _not_ have
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
class_var
</div>
</td>
</tr>
</table>
</div>
in their instance namespaces, so they continue to find
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
class_var
</div>
</td>
</tr>
</table>
</div>
in
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
MyClass.__dict__
</div>
</td>
</tr>
</table>
</div>
and thus return 1.</li> </ul>
### Mutability {#mutability}
Quiz question: What if your class attribute has a **mutable type**? You can manipulate (mutilate?) the class attribute by accessing it through a particular instance and, in turn, end up _manipulating the referenced object that all instances are accessing_ (as pointed out by <a href="http://timothyawiseman.wordpress.com/2012/10/06/class-and-instance-variables-in-python-2-7/" target="_blank" rel="noopener noreferrer">Timothy Wiseman</a>).
This is best demonstrated by example. Let’s go back to the
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
I defined earlier and see how my use of a class variable could have led to problems down the road.
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
My goal was to have the empty list (
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
[]
</div>
</td>
</tr>
</table>
</div>
) as the default value for
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
data
</div>
</td>
</tr>
</table>
</div>
, and for each instance of
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
to have _its own data_ that would be altered over time on an instance-by-instance basis. But in this case, we get the following behavior (recall that
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
takes some argument
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
other_data
</div>
</td>
</tr>
</table>
</div>
, which is arbitrary in this example):
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
This is no good—altering the class variable via one instance alters it for all the others!
_At the namespace level…_ all instances of
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
are accessing and modifying the same list in
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service.__dict__
</div>
</td>
</tr>
</table>
</div>
without making their own
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
data
</div>
</td>
</tr>
</table>
</div>
attributes in their instance namespaces.
We could get around this using assignment; that is, instead of exploiting the list’s mutability, we could assign our
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
objects to have their own lists, as follows:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
In this case, we’re adding
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
s1.__dict__['data'] = [1]
</div>
</td>
</tr>
</table>
</div>
, so the original
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service.__dict__['data']
</div>
</td>
</tr>
</table>
</div>
remains unchanged.
Unfortunately, this requires that
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
users have intimate knowledge of its variables, and is certainly prone to mistakes. In a sense, we’d be addressing the symptoms rather than the cause. We’d prefer something that was correct by construction.
My personal solution: if you’re just using a class variable to assign a default value to a would-be Python instance variable, **_don’t use mutable values_**. In this case, every instance of
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service
</div>
</td>
</tr>
</table>
</div>
was going to override
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Service.data
</div>
</td>
</tr>
</table>
</div>
with its own instance attribute eventually, so using an empty list as the default led to a tiny bug that was easily overlooked. Instead of the above, we could’ve either:
1. Stuck to instance attributes entirely, as demonstrated in the introduction.
2. Avoided using the empty list (a mutable value) as our “default”:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
Of course, we’d have to handle the
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
None
</div>
</td>
</tr>
</table>
</div>
case appropriately, but that’s a small price to pay.</li> </ol>
## So When Should you Use Python Class Attributes? {#so-when-should-you-use-python-class-attributes}
Class attributes are tricky, but let’s look at a few cases when they would come in handy:
1. _Storing constants_. As class attributes can be accessed as attributes of the class itself, it’s often nice to use them for storing Class-wide, Class-specific constants. For example:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
2. _Defining <a href="http://www.python.org/doc/essays/ppt/acm-ws/sld052.htm" target="_blank" rel="noopener noreferrer">default values</a>_. As a trivial example, we might create a bounded list (i.e., a list that can only hold a certain number of elements or fewer) and choose to have a default cap of 10 items:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
We could then create instances with their own specific limits, too, by assigning to the instance’s
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
limit
</div>
</td>
</tr>
</table>
</div>
attribute.
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
1 2 3
<td>
<div class="text codecolorer">
foo = MyClass()<br />
foo.limit = 50<br />
## foo can now hold 50 elements—other instances can hold 10
</div>
</td>
</tr>
This only makes sense if you will want your typical instance of
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
MyClass
</div>
</td>
</tr>
</table>
</div>
to hold just 10 elements or fewer—if you’re giving all of your instances different limits, then
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
limit
</div>
</td>
</tr>
</table>
</div>
should be an instance variable. (Remember, though: take care when using mutable values as your defaults.)</li>
* _Tracking all data across all instances of a given class_. This is sort of specific, but I could see a scenario in which you might want to access a piece of data related to every existing instance of a given class.To make the scenario more concrete, let’s say we have a <div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Person
</div>
</td>
</tr>
</table>
</div>
class, and every person has a
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
name
</div>
</td>
</tr>
</table>
</div>
. We want to keep track of all the names that have been used. One approach might be to <a href="http://stackoverflow.com/questions/328851/printing-all-instances-of-a-class" target="_blank" rel="noopener noreferrer">iterate over the garbage collector’s list of objects</a>, but it’s simpler to use class variables.
_Note that, in this case, </p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
names
</div>
</td>
</tr>
</table>
</div>
will only be accessed as a class variable, so the mutable default is acceptable.</em>
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
We could even use this design pattern to track all existing instances of a given class, rather than just some associated data.
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
* _Performance_ (sort of… see below).</ol>
<div class="pop_out_box is-full_width is-big">
<strong>Related: </strong><a href="https://www.toptal.com/python/tips-and-practices">Python Best Practices and Tips by Toptal Developers</a>
</div>
## Under-the-hood {#under-the-hood}
**Note:** _If you’re worrying about performance at this level, you might not want to be use Python in the first place, as the differences will be on the order of tenths of a millisecond—but it’s still fun to poke around a bit, and helps for illustration’s sake._
Recall that a class’s namespace is created and filled in at the time of the class’s definition. That means that we do just one assignment—_ever_—for a given class variable, while instance variables must be assigned every time a new instance is created. Let’s take an example.
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
When we look at the byte code, it’s again obvious that
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Foo.__init__
</div>
</td>
</tr>
</table>
</div>
has to do two assignments, while
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar.__init__
</div>
</td>
</tr>
</table>
</div>
does just one.
In practice, what does this gain really look like? I’ll be the first to admit that timing tests are highly dependent on often uncontrollable factors and the differences between them are often hard to explain accurately.
However, I think these small snippets (run with the Python <a href="http://docs.python.org/library/timeit.html" target="_blank" rel="noopener noreferrer">timeit</a> module) help to illustrate the differences between class and instance variables, so I’ve included them anyway.
_Note: I’m on a MacBook Pro with OS X 10.8.5 and Python 2.7.2._
<div class="embeddable_form-wrapper for-post">
</div>
### Initialization {#initialization}
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
1 2
<td>
<div class="text codecolorer">
10000000 calls to `Bar(2)`: 4.940s<br />
10000000 calls to `Foo(2)`: 6.043s
</div>
</td>
</tr>
The initializations of
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar
</div>
</td>
</tr>
</table>
</div>
are faster by over a second, so the difference here does appear to be statistically significant.
So why is this the case? One _speculative_ explanation: we do two assignments in
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Foo.__init__
</div>
</td>
</tr>
</table>
</div>
, but just one in
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar.__init__
</div>
</td>
</tr>
</table>
</div>
.
### Assignment {#assignment}
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
_Note: There’s no way to re-run your setup code on each trial with <a href="http://docs.python.org/library/timeit.html" target="_blank" rel="noopener noreferrer">timeit</a>, so we have to reinitialize our variable on our trial. The second line of times represents the above times with the previously calculated initialization times deducted._
From the above, it looks like
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Foo
</div>
</td>
</tr>
</table>
</div>
only takes about 60% as long as
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar
</div>
</td>
</tr>
</table>
</div>
to handle assignments.
Why is this the case? One _speculative_ explanation: when we assign to
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar(2).y
</div>
</td>
</tr>
</table>
</div>
, we first look in the instance namespace (
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar(2).__dict__[y]
</div>
</td>
</tr>
</table>
</div>
), fail to find
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
y
</div>
</td>
</tr>
</table>
</div>
, and then look in the class namespace (
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Bar.__dict__[y]
</div>
</td>
</tr>
</table>
</div>
), then making the proper assignment. When we assign to
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Foo(2).y
</div>
</td>
</tr>
</table>
</div>
, we do half as many lookups, as we immediately assign to the instance namespace (
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
Foo(2).__dict__[y]
</div>
</td>
</tr>
</table>
</div>
).
In summary, though these performance gains won’t matter in reality, these tests are interesting at the conceptual level. If anything, I hope these differences help illustrate the mechanical distinctions between class and instance variables.
## In Conclusion {#in-conclusion}
Class attributes seem to be underused in Python; a lot of programmers have different impressions of how they work and why they might be helpful.
My take: Python class variables have their place within the school of good code. When used with care, they can simplify things and improve readability. But when carelessly thrown into a given class, they’re sure to trip you up.
## _Appendix_: Private Instance Variables {#appendix-private-instance-variables}
One thing I wanted to include but didn’t have a natural entrance point…
Python doesn’t have _private_ variables so-to-speak, but another interesting relationship between class and instance naming comes with name mangling.
In the Python style guide, it’s said that pseudo-private variables should be prefixed with a double underscore: ‘__’. This is not only a sign to others that your variable is meant to be treated privately, but also a way to prevent access to it, of sorts. Here’s what I mean:
<pre><div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<td>
<div class="text codecolorer">
class Bar(object):<br />
def __init__(self):<br />
self.__zap = 1<br />
<br />
a = Bar()<br />
a.__zap<br />
## Traceback (most recent call last):<br />
## File "<stdin>", line 1, in <module><br />
## AttributeError: 'Bar' object has no attribute '__baz'<br />
<br />
## Hmm. So what's in the namespace?<br />
a.__dict__<br />
{'_Bar__zap': 1}<br />
a._Bar__zap<br />
## 1
</div>
</td>
</tr>
Look at that: the instance attribute
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
__zap
</div>
</td>
</tr>
</table>
</div>
is automatically prefixed with the class name to yield
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
_Bar__zap
</div>
</td>
</tr>
</table>
</div>
.
While still settable and gettable using
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;width:550px;">
<table cellspacing="0" cellpadding="0">
<tr>
<td class="line-numbers">
<div>
1<br />
</div>
</td>
<td>
<div class="text codecolorer">
a._Bar__zap
</div>
</td>
</tr>
</table>
</div>
, this name mangling is a means of creating a ‘private’ variable as it prevents you _and_ others from accessing it by accident or through ignorance.
_Edit: as Pedro Werneck kindly pointed out, this behavior is largely intended to help out with subclassing. In the <a href="http://legacy.python.org/dev/peps/pep-0008/#designing-for-inheritance" target="_blank" rel="noopener noreferrer">PEP 8 style guide</a>, they see it as serving two purposes: (1) preventing subclasses from accessing certain attributes, and (2) preventing namespace clashes in these subclasses. While useful, variable mangling shouldn’t be seen as an invitation to write code with an assumed public-private distinction, such as is present in Java._
<div class="pop_out_box is-full_width is-big">
<strong>Related: </strong><a href="https://www.toptal.com/python/top-10-mistakes-that-python-programmers-make">Become More Advanced: Avoid the 10 Most Common Mistakes That Python Programmers Make</a>
</div>
We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!
I've whitelisted your website.
Not now
This website uses cookies to ensure you get the best experience on our website. Learn moreGot it