Static class variables and methods in Python:
- How do I create static class variables or methods in Python?
- Are static class variables possible in Python?
This article will give you a comprehensive answer to these questions!
🔍 Experiment: If we search “static class variables” in the Python documentation we will not find any close to those supposed kinds of variables. If we try searching just the word “static” in the glossary section of the documentation we will see some matches related to “static methods” but nothing with variables.
This is because Python hardly uses the term “static” as opposed to other languages such as C++ or Java where it is more commonly used.
Anyway, as there is some parallelism between the different programming languages we are going to see how what is normally understood as static class variables and static methods are commonly implemented and worked in Python. It is not intended to be exhaustive and it is certainly convenient to have some basic ideas about classes and instances.
Static class variables
If you already have some ideas and want to see briefly how it works and how it can be implemented I suggest you see the following figure where it is practically all summarized.
Next, we’ll explore the code in this graphic in 4 easy steps.
Step 1: Class Attribute in Python
If we try to summarize what “Static class variable” means in other programming languages, we can say that:
💡 Definition: A static class variable is a variable shared by all the instances of a class and there is only one copy of this variable and not a copy in each instance of the class.
In Python, it is common to refer to this concept as “class attribute” but also as “attribute class variable”, “class variable” and even, although less common, as “static variable” or “static class variable”. Here, to make the terminology simple, we adopt the name “class attribute”.
Let’s see how to create and work with “class attributes” in Python.
In the following example, we will model the employees of a company named "A"
with a class called Employees
.
class Employees: company = "A" # class attribute languages = []
We point out that each instance of the class (each concrete employee) belongs to company "A"
with a class attribute company
that has the value "A"
.
Then we create another “class attribute” called language
as an empty list to store later the native language of each employee.
As you are probably thinking this should be an instance attribute. But it is here to help you see that mutable types used as class attributes can give surprising results. We will see this later.
Step 2: Instance Attribute in Python
As you can see it can be created inside the class definition, as you create any variable in Python, but outside the methods starting with def
.
Now we are going to define with __init__()
the property “n
” (from name) with which each object (instance) of the class Employees
must be initialized.
These properties are called “data attributes” or “instance attributes” and correspond to data members in C++.
class Employees: company = "A" # class atribute languages = [] def __init__(self, name): self.n = name # data or instance attribute
Step 3: Creating Instances and Print Class Attribute in Python
Well now we are going to add code to create two instances and print their class attribute:
class Employees: company = "A" # class atribute languages = [] def __init__(self, name): self.n = name # data or instance atribute e1 = Employees("Peter White") e2 = Employees("Paul Green") print(e1.company) # Result: A print(e2.company) # Result: A
Step 4: Modifying a Class Attribute
In Python, we can change the value of a “class attribute” in the code and the changes will be reflected in all instances as we show in the code below:
# This code shows only what is added to the previous code and the results you will see Employees.company = "B" # Changing the value of the class attribute print(e1.company) # Result: B print(e2.company) # Result: B
Step 5: Modifying a Class Attribute to Become an Instance Attribute
And in Python, we can change the “class attribute” to an instance. It could be rare but possible, as we show in the next example with the instance called “e1
“:
# This code shows only what is added to the previous code and the results you will see e1.company = "C" # Changing the class attribute of the instance e1 print(e1.company) # Result: C print(e2.company) # Result: B
Step 6: Understanding Mutable Class Attributes
To finish we should not use as “class attribute” mutable data types like lists or dictionaries because they could have surprising behaviors if we use them as in the example below.
Here we try to put the native languages of each employee as a class attribute and we start it as an empty list.
Clearly, this is an “instance attribute” but let’s force the example a little to see what happens:
# This code shows only what is added to the previous code and the results you will see e1.language.append("english") e2.language.append("spanish") print(e1.language) # Result: ['english', 'spanish'] print(e2.language) # Result: ['english', 'spanish']
As can be seen, the expected results were not obtained.
- On the one hand, this helps to understand that the native language is a property of each employee, that is, of each instance, and should be added as “
self.n
” is inside the__init__()
method. - On the other hand, it helps to see, as stated in point 9.3.5 of the documentation, that implementing mutable data types as “class attributes” can have possibly surprising effects.
To conclude, I suggest you look at the figure at the beginning of this section where we have tried to summarize all these considerations.
Static Methods
As it is said in the documentation, static methods in Python are similar to those found in Java or C++:
A static method is a method that can run without any instance of the class. It doesn’t need to be invoked for a particular object.
If you want to quickly understand how to create and work with a static method I suggest you look at the following figure that summarizes the most important.
The most modern Python implementation, the one we show here, requires the @staticmethod
decorator before the def
that starts the method.
This tells Python that this is a “static method” and not any other.
As a “static method” does not modify or need a class instance to execute it does not require an argument such as “self
” which represents the instance itself from which a method is called
💡 Note: We clarify that using the term “self
” is a convention and another word could be used but this could make the code less readable because everyone understands and expects to see a “self
” in any instance method as the first argument.
Let’s see an example in which we retake the Employees
class built in the previous section. Trying to show something simple we are going to invent a first static method that returns the version of the program when it is called.
As it is seen it is not necessary to create an instance to call it.
class Employees: company = "A" def __init__(self,name): self.n = name @staticmethod def version(): print("""Welcome to Company A's employee system. This is the version 1.0 Type "Employees.help(1)" to see how to enter an object.""") # To call this static method: Employees.version() # Result: Welcome to Company…
In the previous case the “static method” had no argument.
Let’s look at another one that needs, as the first “static method” message says, a 1 to display a first help message to create an object or instance of the class.
# This code shows only what is added to the previous code and the results you will see @staticmethod def help(key): if key == 1: print("To create an object you can follow the next example by putting the employee's complete name in parentheses: e1 = Employees('John Black')") # To call this static method: Employees.help(1) # Show: To create an object…
Conclusions
We have seen how to implement “static class variables” which in Python are more commonly called “class attributes”.
They are simply created like any variable but inside the class definition and outside the “def
” that creates methods.
We’ve also seen some peculiarities that class attributes have in Python.
On the other hand, we have seen how to implement “static methods”, which do not require any instance to be used, using the “@staticmethod
” decorator before the “def
” with which we start the definition of the method itself.
We also saw that it does not require “self
” as the first argument.