What's the point of @staticmethod in Python?

I developed this short test / sample code to better understand 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 does not return any errors. My questions:

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

  • Again, what is the logic for @staticmethod to create static methods that can be called from an instance? Isn't that what static methods are about?

  • Why will the second approach be approved compared to the third? (I assume that since the decorator exists, there is a point to this.) The third option seems simpler and more understandable.

+4
source share
3 answers

Here is the post in static methods . In short:

  • instance methods: requires the instance to be the first argument
  • class methods: the class is required to be the first argument
  • static methods: not required as first argument

Regarding your questions:

  • Yes. Although the variable name self is conditional, it refers to an instance.
  • Static methods can be used to group similar utility methods in one class.
  • For methods inside the class, you need to add self as the first argument or decorate the method with @staticmethod . "Unformed methods" without arguments will cause an error.

It may be more clear how they work when called with arguments. 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 

In general, you can think of each method in terms of access :

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

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

Note: there is a way to access the components of a class from an instance method using self.__class__ , thereby eliminating 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 a look at the Raymond Hettinger talk Python Class Development Toolkit, which clearly explains the purpose of each type of method with examples.

+4
source

Here are the answers to your question:

Question 1:

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

No. This is not completely True . self means that the first argument to the function must be an instance of the class. For instance:

 def my_class_function(self) 

may be called as:

 self.my_class_function() OR, my_class_function(self) 

In addition, self should not be used as a reference to a class object. You can use anything (as far as a valid variable is), but using self is the standard that follows everywhere.

Question 2:

Again, what is the @staticmethod logic about creating static methods that can be called from an instance? Isn't that what static methods are about?

@staticmethod variable is used with functions in which you do not need a reference to the class object inside the function, i.e. you do not use self to access any property or function of the class.

Question 3:

Why will the second approach be approved compared to the third? (I assume that since the decorator exists, there is a point to this.) The third option seems simpler and more understandable.

Using the second approach, using @staticmetod , you can call your function from outside the class using the class object, unlike your third approach (without using a decorator), since the scope of the function is inside the class.

+1
source

The methods act on the instances they invoke. The instance is passed as the first parameter, usually called self .

Class methods are similar, but act on a common class object, and not on one of the instances. They are convenient as constructors and factory functions, as well as for setting up configuration and other situations that affect a class or all its instances at the same time, and not on individual instances.

The third option, static methods, is a strange person. They pass neither an instance nor a class. They are good for embedding utility functions in the structure of the program class for organizational purposes, but in such a way that they clearly signal (to code browsers, "linting" and program checking tools, etc.) that you intentionally do not depend on the instance or value class. Thus, you will not receive warnings of "variables declared but never used" that self is not used.

From the perspective of the caller, static methods look like any other method call. If you didn't have @staticmethod available, you can just use a regular instance or class method (albeit with the risk of a redundant variable not used!) Linter warnings). Therefore, unlike class methods, static methods are a completely optional part of Python. They do not add any functionality to the language; instead, they provide an opportunity to make the intentions of the developer more clear.

+1
source

All Articles