What is the advantage of using static methods?

55,752

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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.

Solution 5

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
Share:
55,752

Related videos on Youtube

Curious2learn
Author by

Curious2learn

Updated on July 08, 2022

Comments

  • Curious2learn
    Curious2learn almost 2 years

    I ran into unbound method error in python with the code

    import random
    
    class Sample(object):
        '''This class defines various methods related to the sample'''
    
        def drawSample(samplesize,List):
            sample=random.sample(List,samplesize)
            return sample
    
    Choices=range(100)
    print Sample.drawSample(5,Choices)
    

    After reading many helpful posts here, I figured how I could add @staticmethod above to get the code working. I am a python newbie. Can someone please explain why one would want to define static methods? Or, why are not all methods defined as static methods?

    • user1066101
      user1066101 over 14 years
      This is an odd question. Static methods are a design necessity. It isn't an "advantage" thing. You use them because you must. It's a design feature of a class to have static methods. Are you asking what static methods are in the first place? I think the question could be reworded to more clearly define what you need to know.
    • Curious2learn
      Curious2learn over 14 years
      No, I did not want to know what they are. What I wanted to know was why is it a "necessity", which has become clear from the answers given by others. That is when would you define it rather than the non-static methods. Thanks.
    • RFV
      RFV over 5 years
      @S.Lott: When is using a staticmethod a necessity as opposed to using a normal class method? As far as I can tell, a class method can do everything a staticmethod can. Staticmethod does have "advantages" as listed elsewhere in this post, but I can"t see any reasons why a class method can't be used in any place that a static method can be used, hence making it a necessity.
  • Curious2learn
    Curious2learn over 14 years
    Thanks David. But why then not define every method as a static method, since they also work on instances. Are there any drawbacks of doing so?
  • Felix Kling
    Felix Kling over 14 years
    @Curious2learn: No, with static methods you have no access to the instance: The instance is ignored except for its class.
  • extraneon
    extraneon over 14 years
    That argument would be true in Java, where functions can not live by itself but are always defined in the context of a class. But in Python you can have functions and static class functions. This answer doesn't really show why to choose a static method in stead of a method not in a class.
  • extraneon
    extraneon over 14 years
    But why not a package math? Python has packages for that, you don't need a class definition to create a namespace.
  • Pratik Deoghare
    Pratik Deoghare over 14 years
    @extraneon: Yup dude I know that but I wanted to have something simple and familiar for explanation so I used Math. That is why I capitalized M.
  • Javier
    Javier over 14 years
    The OP didn't ask what are static methods. He asked what's their advantage. You're explaining how to use them, not how are they useful. In your particular example, a namespace would make much more sense.
  • Javier
    Javier over 14 years
    You said "almost". Is there a place where they can be better than the alternatives?
  • Stefan
    Stefan over 14 years
    @Javier: I can't think of one, but there probably is one, why would that method be included in the Python library otherwise?
  • Pratik Deoghare
    Pratik Deoghare over 14 years
    @Javier Badia- :) Somebody(a c# programmer) might want to use them in this way. Also look at stackoverflow.com/questions/2438473/…
  • Charles Duffy
    Charles Duffy over 14 years
    @extraneon - that's more a matter of code organizational preferences; having static methods gives one the extra option.
  • Curious2learn
    Curious2learn over 14 years
    @Felix - Thanks. This clarifies why every method should not be a static method.
  • Charles Merriam
    Charles Merriam over 14 years
    @Javier, @Georg: You have great faith that the Python corpus does not have cruft.
  • Curious2learn
    Curious2learn over 14 years
    Thanks for the comment. I did need a class in this case because I want to work with the sample drawn. No I did not use a static method, but wanted to learn about, since I came across the term when looking up information on the error message that I got. But your advice about collecting the functions into a module without defining a class would be helpful for other functions that I need. So thanks.
  • MestreLion
    MestreLion about 12 years
    @Curious2learn: Not every, but some methods are useful as static methods. Think about an example Locale class, whose instances will be locales (duh). A getAvailableLocales() method would be a nice example of a static method of such class: it clearly belong to the Locale class, while also clearly does not belong to any particular instance.
  • MestreLion
    MestreLion about 12 years
    -1: Good and correct explanation, but a very poorly chosen example: theres no reason for your made up Math to be a class in the first place, a module would be a better fit. Try to find an example of a class that make sense as a class, not one that "nobody will want to create object of".
  • MestreLion
    MestreLion about 12 years
    And then give an example of a legit use-case for one (or some) of the classes' methods to be static, but not all. If all of a classes' methods are static, class should be a module. If none are static, then you are not answering the question.
  • MestreLion
    MestreLion about 12 years
    +1: That was a nice explanation on some misconceptions the OP had. And you were very honest to say, upfront, that you were not actually answering his question about static methods, but you rather gave a much better solution saying his problem does not require classes at all.
  • MestreLion
    MestreLion about 12 years
    -1: This answer does not present any use case of staticmethod or any explanation of what a classmethod is or why and how it is "better" than static ones.
  • MestreLion
    MestreLion about 12 years
    @CharlesMerriam: Of course static methods have their usage, otherwise it would have been dropped or deprecated in Python 3 (where most of the legacy cruft was removed). There is not a single word against staticmethod in docs to support your claim that it is cruft, or Georg's claim that classmethod should be used instead).
  • MestreLion
    MestreLion about 12 years
    +1: Finally a great explanation on what static methods and class methods are. Although you didn't explain why one would ever want to use a static method, at least you clearly explained in a simple example what both are much better than official docs does.
  • MestreLion
    MestreLion about 12 years
    ... and it's not a class method either, since it may not need to access any of the classes' methods.
  • Oddthinking
    Oddthinking almost 7 years
    An editor points out that a static method can access the class attributes, by explicitly navigating down from the class_name.attribute, just not cls.attribute or self.attribute. This is true for "public" attributes. By convention, you shouldn't access attributes hidden with an underscore, or names mangled with two underscores, in this way. It also means your code will be more fragile when attributes shift places on the inheritance hierarchy.
  • Zhuoyun Wei
    Zhuoyun Wei over 6 years
    This should be the accepted answer. The fact that the static method on any instances and the class itself are the same object is a real advantage, especially when you have a lot of instances (e.g. each instance for a mutable database record).
  • Alex
    Alex about 6 years
    +1 and agree with @ZhuoyunWei. Only answer that explains the few reasons why a static method is sometimes preferable than a class method (though 1 and 3 are really the same reason).
  • Exu
    Exu almost 5 years
    The best answer to "why static method", but original question also asked "why aren't all methods static?". Short "no access to instance attributes" would cover that too.
  • user101
    user101 over 4 years
    Your example does not explain why not using @classmethod since with a class method you could also do Math.floor(3.14)
  • Boris Churzin
    Boris Churzin almost 4 years
    A quote from Guido that helps to decide when to use staticmethods (never): "We all know how limited static methods are. (They’re basically an accident — back in the Python 2.2 days when I was inventing new-style classes and descriptors, I meant to implement class methods but at first I didn’t understand them and accidentally implemented static methods first. Then it was too late to remove them and only provide class methods."
  • Boris Churzin
    Boris Churzin almost 4 years
    IMO the only real advantage is that you can override it in a subclass, but even that has some feeling that you are doing something wrong OOP-wise, in what use case would you do that?
  • Alex
    Alex over 3 years
    3. - if there is not a state, then why create a class in the first place? module functions would be just as good, with less code.
  • juanpa.arrivillaga
    juanpa.arrivillaga almost 3 years
    @ZhuoyunWei this is wrong. Using a staticmethod does not save memory, even if you have many instances, instances don't carry around their own instance methods, bound method objects are ephemeral. This answer is misleading.
  • Guzman Ojero
    Guzman Ojero about 2 years
    @BorisChurzin source of that quote?
  • Boris Churzin
    Boris Churzin about 2 years