Search code examples
pythonpython-3.xpython-decorators

Difference between having @staticmethod and not having it


In Python 3.x what can I do with bar() that I cannot do with foo()?

class A:
    def foo():
        print("some code")

    @staticmethod
    def bar():
        print("some code")

Note: I initially forgot to specify self as an argument to foo(), but I'm leaving the mistake there, since the answers andress that.


Solution

  • a staticmethod is a method that does not require an object as its first parameter. This means it is a method useful to the class itself and all instantiations of it, rather than just instances of it (object initialized as A().

    What this means in practical terms, is that Python does not implicitly send the object itself as a parameter. Your first method will break once you call it:

    >>> a.foo()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: foo() takes 0 positional arguments but 1 was given
    

    This is because Python supplies object methods with the object itself as a first parameter. Hence the ubiquitous self argument:

    def foo(self): #Proper signature
    

    On the other hand,

    A.bar()
    

    will work just fine, and so will

    a.bar()
    

    The object is not supplied as a first argument. Use staticmethods for methods that are supposed to be helpful to the class and its instances, but do not require knowledge of either. Usually I use these as utility functions.

    Note there is a third version, a classmethod, which is similar to a regular method in that it accepts a first parameter by default - the class of the caller. In this case the minimal signature is

    @classmethod
    def operateOnClass(cls):
    

    Use this to make changes that affect all instances, such as changing class variables.