138

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

2
  • 25
    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. Commented Mar 15, 2010 at 0: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. Commented Jan 21, 2019 at 4:40

10 Answers 10

279

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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).
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?
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.
@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.
The first and second advantage is not belongs to only static method, class method also ahs that
170

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.

5 Comments

@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.
... and it's not a class method either, since it may not need to access any of the classes' methods.
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.
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."
36

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.

Comments

33

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.

1 Comment

Clear way to clarify a opinion
29

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.

7 Comments

But why not a package math? Python has packages for that, you don't need a class definition to create a namespace.
@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.
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.
-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".
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.
|
15

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) 

Comments

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

4 Comments

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: No, with static methods you have no access to the instance: The instance is ignored except for its class.
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 - that's more a matter of code organizational preferences; having static methods gives one the extra option.
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.

Comments

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 

5 Comments

You said "almost". Is there a place where they can be better than the alternatives?
@Javier: I can't think of one, but there probably is one, why would that method be included in the Python library otherwise?
@Javier, @Georg: You have great faith that the Python corpus does not have cruft.
-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.
@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).
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.