What is the purpose of static methods? How do I know when to use one?

Question:

I ran into unbound method error in python with this code:

import random

class Sample(object):
    def drawSample(samplesize, List):
        sample = random.sample(List, samplesize)
        return sample

Choices=range(100)
print(Sample.drawSample(5, Choices))

I was able to fix the problem by adding @staticmethod to the method. However, I don’t really understand the situation.

What is the point of using "static" methods? Why does it solve the problem in this code, and why are they ever necessary? Conversely, why would I ever not want to do it (i.e., why is extra code needed to make the method static)?

Asked By: Curious2learn

||

Answers:

static methods are great because you don’t have to declare an instance of the object to which the method belongs.

python’s site has some great documentation on static methods here:
http://docs.python.org/library/functions.html#staticmethod

Answered By: David Fox

Static methods have almost no reason-to-be in Python. You use either instance methods or class methods.

def method(self, args):
    self.member = something

@classmethod
def method(cls, args):
    cls.member = something

@staticmethod
def method(args):
    MyClass.member = something
    # The above isn't really working
    # if you have a subclass
Answered By: Georg Schölly

Why one would want to define static methods?

Suppose we have a class called Math then

nobody will want to create object of class Math
and then invoke methods like ceil and floor and fabs on it.

So we make them static.

For example doing

>> Math.floor(3.14)

is much better than

>> mymath = Math()
>> mymath.floor(3.14)

So they are useful in some way. You need not create an instance of a class to use them.

Why are not all methods defined as static methods?

They don’t have access to instance variables.

class Foo(object):
    def __init__(self):
        self.bar = 'bar'

    def too(self):
        print self.bar

    @staticmethod
    def foo():
        print self.bar

Foo().too() # works
Foo.foo() # doesn't work

That is why we don’t make all the methods static.

Answered By: Pratik Deoghare

When you call a function object from an object instance, it becomes a ‘bound method’ and gets the instance object itself is passed in as a first argument.

When you call a classmethod object (which wraps a function object) on an object instance, the class of the instance object gets passed in as a first argument.

When you call a staticmethod object (which wraps a function object), no implicit first argument is used.

class Foo(object):

    def bar(*args):
        print args

    @classmethod
    def baaz(*args):
        print args

    @staticmethod
    def quux(*args):
        print args

>>> foo = Foo()

>>> Foo.bar(1,2,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got int instance instead)
>>> Foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> Foo.quux(1,2,3)
(1, 2, 3)

>>> foo.bar(1,2,3)
(<Foo object at 0x1004a4510>, 1, 2, 3)
>>> foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> foo.quux(1,2,3)
(1, 2, 3)
Answered By: Matt Anderson

Static methods have limited use, because they don’t have access to the attributes of an instance of a class (like a regular method does), and they don’t have access to the attributes of the class itself (like a class method does).

So they aren’t useful for day-to-day methods.

However, they can be useful to group some utility function together with a class – e.g. a simple conversion from one type to another – that doesn’t need access to any information apart from the parameters provided (and perhaps some attributes global to the module.)

They could be put outside the class, but grouping them inside the class may make sense where they are only applicable there.

You can also reference the method via an instance or the class, rather than the module name, which may help the reader understand to what instance the method is related.

Answered By: Oddthinking

This is not quite to the point of your actual question, but since you’ve said you are a python newbie perhaps it will be helpful, and no one else has quite come out and said it explicitly.

I would never have fixed the above code by making the method a static method. I would either have ditched the class and just written a function:

def drawSample(samplesize,List):
    sample=random.sample(List,samplesize)
    return sample

Choices=range(100)
print drawSample(5,Choices)

If you have many related functions, you can group them in a module – i.e, put them all in the same file, named sample.py for example; then

import sample

Choices=range(100)
print sample.drawSample(5,Choices)

Or I would have added an __init__ method to the class and created an instance that had useful methods:

class Sample(object):
'''This class defines various methods related to the sample'''

    def __init__(self, thelist):
        self.list = thelist

    def draw_sample(self, samplesize):
        sample=random.sample(self.list,samplesize)
        return sample

choices=Sample(range(100))
print choices.draw_sample(5)

(I also changed the case conventions in the above example to match the style recommended by PEP 8.)

One of the advantages of Python is that it doesn’t force you to use classes for everything. You can use them only when there is data or state that should be associated with the methods, which is what classes are for. Otherwise you can use functions, which is what functions are for.

Answered By: Vicki Laidler

See this article for detailed explanation.

TL;DR

1.It eliminates the use of self argument.

2.It reduces memory usage because Python doesn’t have to instantiate a bound-method for each object instiantiated:

>>>RandomClass().regular_method is RandomClass().regular_method
False
>>>RandomClass().static_method is RandomClass().static_method
True
>>>RandomClass.static_method is RandomClass().static_method
True

3.It improves code readability, signifying that the method does not depend on state of the object itself.

4.It allows for method overriding in that if the method were defined at the module-level (i.e. outside the class) a subclass would not be able to override that method.

Answered By: zanetu

Because namespacing functions is nice (as was previously pointed out):

  1. When I want to be explicit about methods that don’t change the state of the object, I use static methods. This discourages people on my team to start changing the object’s attributes in those methods.

  2. When i refactor really rotten code, I start by trying to make as many methods @staticmethod as possible. This allows me then to extract these methods into a class – though I agree, this is rarely something I use, it did came in helpful a few times.

Answered By: vlad-ardelean

In my estimation, there is no single performance benefit of using @staticmethods compared to just defining the function outside of and separate from the class it would otherwise be a @staticmethod of.

The only thing I would say justifies their existence is convenience. Static methods are common in other popular programming languages, so why not python? If you want to create a function with behavior that is very closely associated with the class you are creating it for but it doesn’t actually access/modify the internal data of an instance of the class in a way that justifies conceptualizing it as a typical method of that class then slap a @staticmethod above it and anyone reading your code will immediately learn a lot about the nature of the method and its relationship to the class.

One thing I occasionally like to do is place functionality that my class uses internally a lot into private @staticmethods. That way I do not clutter the API exposed by my module with methods that no one using my module would ever need to see let alone use.

Answered By: Garrett Gutierrez

The alternatives to a staticmethod are: classmethod, instancemethod, and function. If you don’t know what these are, scroll down to the last section. If a staticmethod is better than any of these alternatives, depends on for what purpose it is written.

advantages of the Python static method

  • If you don’t need access to the attributes or methods of the class or instance, a staticmethod is better than a classmethod or instancemethod. That way it is clear (from the @staticmethod decorator) that the class’ and instance’s state is not read or modified. However, using a function makes that distinction even clearer (see disadvantages).
  • The call signature of a staticmethod is the same as that of a classmethod or instancemethod, namely <instance>.<method>(<arguments>). Hence it can easily be replaced by one of the three if that is needed later on or in a derived class. You can’t do that with a simple function.
  • A staticmethod can be used instead of a function to make clear that it subjectively belongs to a class and to prevent namespace conflicts.

disadvantages of the Python static method

  • It cannot access attributes or methods of the instance or class.
  • The call signature of a staticmethod is the same as that of a classmethod or instancemethod. This masks the fact that the staticmethod does not actually read or modify any object information. This makes code harder to read. Why not just use a function?
  • A staticmethod is difficult to re-use if you ever need to call it from outside the class/instance where it was defined. If there is any potential for re-use, a function is the better choice.
  • The staticmethod is seldom used, so people reading code that includes one may take a little longer to read it.

alternatives to a static method in Python

To address discuss the advantages of the staticmethod, we need to know what the alternatives are and how they differ from each other.

  • The staticmethod belongs to a class but cannot access or modify any instance or class information.

There are three alternatives to it:

  • The classmethod has access to the caller’s class.
  • The instancemethod has access to the caller’s instance and its class.
  • The function has nothing to do with classes. It is the closest in capability to the staticmethod.

Here’s what this looks like in code:

# function
# has nothing to do with a class
def make_cat_noise(asker_name):
    print('Hi %s, mieets mieets!' % asker_name)

# Yey, we can make cat noises before we've even defined what a cat is!
make_cat_noise('JOey')  # just a function

class Cat:
    number_of_legs = 4

    # special instance method __init__
    def __init__(self, name):
        self.name = name

    # instancemethod
    # the instance (e.g. Cat('Kitty')) is passed as the first method argument
    def tell_me_about_this_animal(self, asker_name):
        print('Hi %s, This cat has %d legs and is called %s'
              % (asker_name, self.number_of_legs, self.name))

    # classmethod
    # the class (e.g. Cat) is passed as the first method argument
    # by convention we call that argument cls
    @classmethod
    def tell_me_about_cats(cls, asker_name):
        print("Hi %s, cats have %d legs."
              % (asker_name, cls.number_of_legs))
        # cls.name  # AttributeError because only the instance has .name
        # self.name  # NameError because self isn't defined in this namespace

    # staticmethod
    # no information about the class or the instance is passed to the method
    @staticmethod
    def make_noise(asker_name):
        print('Hi %s, meooow!' % asker_name)
        # class and instance are not accessible from here

# one more time for fun!
make_cat_noise('JOey')  # just a function

# We just need the class to call a classmethod or staticmethod:
Cat.make_noise('JOey')  # staticmethod
Cat.tell_me_about_cats('JOey')  # classmethod
# Cat.tell_me_about_this_animal('JOey')  # instancemethod -> TypeError

# With an instance we can use instancemethod, classmethod or staticmethod
mycat = Cat('Kitty')  # mycat is an instance of the class Cat
mycat.make_noise('JOey')  # staticmethod
mycat.tell_me_about_cats('JOey')  # classmethod
mycat.tell_me_about_this_animal('JOey')  # instancemethod
Answered By: Joooeey
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.