126

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)?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Curious2learn
  • 31,692
  • 43
  • 108
  • 125
  • 24
    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. – Curious2learn Mar 15 '10 at 00:41
  • 5
    @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. – RFV Jan 21 '19 at 04:40

10 Answers10

263

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.

zanetu
  • 3,740
  • 1
  • 21
  • 17
  • 9
    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). – Zhuoyun Wei Feb 12 '18 at 07:47
  • 1
    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? – Boris Churzin Jul 06 '20 at 18:45
  • 3
    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. – Alex Dec 09 '20 at 15:19
  • @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. – juanpa.arrivillaga Jul 20 '21 at 04:52
166

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.

Oddthinking
  • 24,359
  • 19
  • 83
  • 121
  • 11
    @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 May 03 '12 at 04:01
  • 1
    ... and it's not a class method either, since it may not need to access any of the classes' methods. – MestreLion May 03 '12 at 11:05
  • 1
    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. – Oddthinking Sep 12 '17 at 23:19
  • 1
    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 Jul 06 '20 at 18:40
  • 1
    @GuzmanOjero https://mail.python.org/pipermail/python-ideas/2012-May/014969.html – Boris Churzin Apr 04 '22 at 06:53
33

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.

tripleee
  • 175,061
  • 34
  • 275
  • 318
Vicki Laidler
  • 3,415
  • 1
  • 20
  • 17
27

alternatives to a static method in Python

To discuss the advantages of the @staticmethod, we need to know what the alternatives are and how they differ from each other. (You can scroll down to advantages and disadvantages if you're familiar with @classmethod and co.)

  • 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 instance method (normal method) 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

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 instance method. 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 instance method, 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 instance method. 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.
Joooeey
  • 3,394
  • 1
  • 35
  • 49
26

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.

Pratik Deoghare
  • 35,497
  • 30
  • 100
  • 146
  • 12
    But why not a package math? Python has packages for that, you don't _need_ a class definition to create a namespace. – extraneon Mar 13 '10 at 13:55
  • 6
    @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`. – Pratik Deoghare Mar 13 '10 at 14:06
  • 6
    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 Mar 13 '10 at 14:46
  • @Javier Badia- :) Somebody(a c# programmer) might want to use them in this way. Also look at http://stackoverflow.com/questions/2438473/what-is-the-advantage-of-using-static-methods-in-python/2438478#2438478 – Pratik Deoghare Mar 13 '10 at 15:09
  • 4
    -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 May 03 '12 at 04:10
  • 3
    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 May 03 '12 at 04:13
  • 1
    Your example *does not* explain why not using `@classmethod` since with a class method you could also do `Math.floor(3.14)` – user101 Nov 04 '19 at 16:38
14

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)
Matt Anderson
  • 19,311
  • 11
  • 41
  • 57
2

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

David Fox
  • 10,603
  • 9
  • 50
  • 80
  • 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? – Curious2learn Mar 13 '10 at 13:23
  • 4
    @Curious2learn: No, with static methods you have no access to the instance: *The instance is ignored except for its class.* – Felix Kling Mar 13 '10 at 13:31
  • 4
    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 Mar 13 '10 at 13:54
  • 1
    @extraneon - that's more a matter of code organizational preferences; having static methods gives one the extra option. – Charles Duffy Mar 13 '10 at 15:18
2

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.

1

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
Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
  • You said "almost". Is there a place where they can be better than the alternatives? – Javier Mar 13 '10 at 14:46
  • @Javier: I can't think of one, but there probably is one, why would that method be included in the Python library otherwise? – Georg Schölly Mar 13 '10 at 14:57
  • 1
    @Javier, @Georg: You have great faith that the Python corpus does not have cruft. – Charles Merriam Mar 13 '10 at 17:12
  • -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 May 03 '12 at 04:26
  • @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 May 03 '12 at 04:29
1

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.

vlad-ardelean
  • 7,480
  • 15
  • 80
  • 124