3.9 static methods#

In previous section we wrote a code to count number of instances of class using a public attribute of a class. If we make this attribute private , we can create a method inside the class to acquire its value. In following example, we do it by PopulationCount method.

class Insan:
    __counter = 0

    def __init__(self):
        type(self).__counter += 1

    def PopulationCount(self):
        return Insan.__counter


ali = Insan()
print(ali.PopulationCount())
hasan = Insan()
print(hasan.PopulationCount())
1
2

So far so good. But we have a problem, first, the PopulationCount does not have anything to do with the instance of class Insan i.e. ali and second, if we want access this method directly from class’ instance, we will encounter an error as shown below.

# uncomment following line
# Insan.PopulationCount()  # TypeError

This is because, the method PopulationCount takes one input argument self. When we call this method using instance of class, python implicit puts the class’ instance, ali in this case, as an input argument but now we are not calling this method from instance, so python does not provide the implicit first input argument to this method. We could however, avoid this error by explicitly providing the instance ali as first input argument.

Insan.PopulationCount(ali)
2

However, this is not a good way. An alternative would be to avoid the self statement when defining the method in the class.

class Insan:
    __counter = 0

    def __init__(self):
        type(self).__counter += 1

    def PopulationCount():
        return Insan.__counter


Insan.PopulationCount()
0

But now we can’t access this method from the instance, because when we access this method from instance, python implicitly gives instance ali as first input argument to this method but the method does not take any input argument as the error message also depicts this.

# uncomment following two lines
# ali = Insan()  # TypeError
# ali.PopulationCount()

The way to solve this problem is to put the decorate @staticmethod. By doing so, python will not put the instance implicitly as first input argument.

class Insan:
    __counter = 0

    def __init__(self):
        type(self).__counter += 1

    @staticmethod
    def PopulationCount():
        return Insan.__counter


print(Insan.PopulationCount())
ali = Insan()
print(ali.PopulationCount())
hasan = Insan()
print(hasan.PopulationCount())
print(Insan.PopulationCount())
0
1
2
2

why to use them?#

Static methods are used to group a utility function with a class.

class Dates:
    def __init__(self, date):
        self.date = date

    def getDate(self):
        return self.date

    @staticmethod
    def toDashDate(date):
        return date.replace("/", "-")


date = Dates("15-12-2016")
dateFromDB = "15/12/2016"
dateWithDash = Dates.toDashDate(dateFromDB)

since toDashDate works only for dates, it’s logical to keep it inside the Dates class Consider another example. Suppose we have a large number of examples which perform mathematical functions such as ceil, multiply, exponent, divide on some input arguments. Then it would be logical to just group all such functions one one class such as math and use the functions as math.ceil(2.2) or math.exp(2.3) etc.

class math():

    @staticmethod
    def ceil(x):
        # perform ceil operation
        return

    @staticmethod
    def exp(x):
        # perform exponent operation
        return

    # more methods

This increases code readability.

Total running time of the script: ( 0 minutes 0.003 seconds)

Gallery generated by Sphinx-Gallery