Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the point of @staticmethod in Python?

I've developed this short test/example code, in order to understand better how static methods work in Python.

class TestClass:
    def __init__(self, size):
        self.size = size

    def instance(self):
        print("regular instance method - with 'self'")

    @staticmethod
    def static():
        print("static instance method - with @staticmethod")

    def static_class():
        print("static class method")


a = TestClass(1000)

a.instance()
a.static()
TestClass.static_class()

This code works correctly, it doesn't return any errors. My questions are:

  1. Do I understand correctly that "self" can be understood as something like "this method will be called from an instance"?

  2. Then again, what's the logic behind @staticmethod - is it to create static methods which can be called from an instance? Isn't that exactly not what static methods are about?

  3. Why would the second approach be favored over the third one? (I assume that since the decorator exists, there is a point to this.) The 3rd option seems to be the simpler and more straightforward.

like image 849
rbrtk Avatar asked Nov 27 '16 21:11

rbrtk


People also ask

What is the point of @staticmethod Python?

@staticmethod variable is used with the functions where you do not need any reference to the class' object within the function i.e. you do not any usage of self for accessing any of class' property or function.

Is @staticmethod necessary in Python?

Having a static method avoids that. There are very few situations where static-methods are necessary in Python. The @staticmethod form is a function decorator. Also see classmethod() for a variant that is useful for creating alternate class constructors.

What is the benefit of the @staticmethod decorator?

This decorator exists so you can create class methods that are passed the actual class object within the function call, much like self is passed to any other ordinary instance method in a class. This follows the static factory pattern very well, encapsulating the parsing logic inside of the method itself.

What is @staticmethod in Python class?

What is a static method? Static methods in Python are extremely similar to python class level methods, the difference being that a static method is bound to a class rather than the objects for that class. This means that a static method can be called without an object for that class.


2 Answers

Here is a post on static methods. In summary:

  • instance methods: require the instance as the first argument
  • class methods: require the class as the first argument
  • static methods: require neither as the first argument

Regarding your questions:

  1. Yes. While the variable name self is a convention, it pertains to the instance.
  2. Static methods can be used to group similar utility methods under the same class.
  3. For methods within a class, you either need to add self as the first argument or decorate the method it with @staticmethod. "Non-decorated methods" without arguments will raise an error.

It may be more clear to see how these work when called with arguments. A modified example:

class TestClass:

    weight = 200                             # class attr 

    def __init__(self, size):
        self.size = size                     # instance attr

    def instance_mthd(self, val):
        print("Instance method, with 'self':", self.size*val)

    @classmethod
    def class_mthd(cls, val):
        print("Class method, with `cls`:", cls.weight*val)

    @staticmethod
    def static_mthd(val):
        print("Static method, with neither args:", val)

a = TestClass(1000)

a.instance_mthd(2)
# Instance method, with 'self': 2000

TestClass.class_mthd(2)
# Class method, with `cls`: 400

a.static_mthd(2)
# Static method, with neither args: 2

Overall, you can think of each method in terms of access:

  • If you need to access the instance or an instance component (e.g. an instance attribute), use an instance method as it passes self as the first argument.
  • Similarly, if you need to access a class, use a class method.
  • If access to neither an instance nor class is important, you can use a static method.

Notice in the example above, the same argument is passed for each method type, but access to instance and class attributes differ via self and cls respectively.

Note, there is a way to access class components from an instance method by using self.__class__, thereby obviating the need for a class method:

    ...

    def instance_mthd2(self, val):
        print("Instance method, with class access via `self`:", self.__class__.weight*val)
    ...

a.instance_mthd2(2)
# Instance method, with class access via `self`: 400

REF: I recommend watching Raymond Hettinger's talk Python's Class Development Toolkit, which elucidates the purpose for each method type clearly with examples.

like image 99
pylang Avatar answered Sep 28 '22 12:09

pylang


Methods act on the instances on which they're invoked. The instance is passed as the first parameter, conventionally called self.

Class methods are similar, but act on the overall class object rather than one of the instances. They're handy as constructors and factory functions, or for configuration setting and other situations that affect the class or all of its instances at once, rather than individual instances.

The third option, static methods, is odd man out. They don't pass either the instance or the class. They're good for nesting utility functions within a program's class structure for organizational purposes, but in a way that clearly signals (to code reviewers, "linting" and program checking tools, etc.) that you are intentionally not depending on instance or class values. That way, you won't get "variable declared but never used" warnings about that unused self.

From the caller's point of view, static methods look like any other method call. If you didn't have @staticmethod available, you could just use a normal instance or class method (albeit at the risk of excess "variable not used!!" linter warnings). So unlike class methods, static methods are an entirely optional part of Python. They don't add any functionality to the language; instead, they provide a way to make the developer's intentions clearer.

like image 35
Jonathan Eunice Avatar answered Sep 28 '22 13:09

Jonathan Eunice