Static variables and methods in Python

Bringing a bit of C++ into Python.
21 July 2011
~
2 min read

How to declare a data member or a method static in Python? Static means, that the member is on a class level rather on the instance level. Static variables exist only on class level and aren't instantiated. If you change a static variable in one instance of the class, the change will affect its value in all other instances.

Static methods don't refer to any instance of the class and can be called outside of it. They also cannot access any non-static data members of the class for obvious reasons. Let's have a look how to get some static from Python.

Variables

All variables defined on the class level in Python are considered static. See this example:

class Example:
    staticVariable = 5 # Access through class

print Example.staticVariable # prints 5

# Access through an instance
instance = Example()
print instance.staticVariable # still 5

# Change within an instance
instance.staticVariable = 6
print instance.staticVariable # 6
print Example.staticVariable # 5

# Change through the class
class Example.staticVariable = 7
print instance.staticVariable # still 6
print Example.staticVariable # now 7

Seems pretty straight-forward. The only confusion might arise from the fact that you can have two different variables in your class with the same name (one static and one ordinary). I wouldn't recommend relying on that behaviour in your code.

Methods

With static methods, it gets a little more complicated. In Python, there are two ways of defining static methods within a class.

@staticmethod

A method decorated with this decorator only shares the namespace with the class. Note that no arguments are mandatory in the method definition. A static method defined this way can access the class' static variables. See the following example:

class Example:
    name = "Example"

    @staticmethod
    def static():
        print "%s static() called" % Example.name

class Offspring1(Example):
    name = "Offspring1"

class Offspring2(Example):
    name = "Offspring2"

    @staticmethod
    def static():
        print "%s static() called" % Offspring2.name

Example.static() # prints Example
Offspring1.static() # prints Example
Offspring2.static() # prints Offspring2

@classmethod

The difference between class method and static method in Python is, that class method recieves one mandatory argument - a class it was called from. Let's take a look:

class Example:
    name = "Example"

    @classmethod
    def static(cls):
        print "%s static() called" % cls.name

class Offspring1(Example):
    name = "Offspring1"
    pass

class Offspring2(Example):
    name = "Offspring2"

    @classmethod
    def static(cls):
        print "%s static() called" % cls.name

Example.static()    # prints Example
Offspring1.static() # prints Offspring1
Offspring2.static() # prints Offspring2

Which one should you use? The first option allows you to only access the static variables in the same class. With the second approach, you'll be able to modify class variables of the subclasses without the neccessity of redefining the method when using inheritance.

Personally, I prefer the first variant because I think it's a little cleaner, but the second variant might come useful in certain situations as well.

Sources