Maybe a bit of example code will help: Notice the difference in the call signatures of foo, class_foo and static_foo:
class A(object):
def foo(self, x):
print(f"executing foo({self}, {x})")
@classmethod
def class_foo(cls, x):
print(f"executing class_foo({cls}, {x})")
@staticmethod
def static_foo(x):
print(f"executing static_foo({x})")
a = A()
Below is the usual way an object instance calls a method. The object instance, a, is implicitly passed as the first argument.
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>, 1)
With classmethods, the class of the object instance is implicitly passed as the first argument instead of self.
a.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)
You can also call class_foo using the class. In fact, if you define something to be
a classmethod, it is probably because you intend to call it from the class rather than from a class instance. A.foo(1) would have raised a TypeError, but A.class_foo(1) works just fine:
A.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)
One use people have found for class methods is to create inheritable alternative constructors.
With staticmethods, neither self (the object instance) nor cls (the class) is implicitly passed as the first argument. They behave like plain functions except that you can call them from an instance or the class:
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
Staticmethods are used to group functions which have some logical connection with a class to the class.
foo is just a function, but when you call a.foo you don't just get the function,
you get a "partially applied" version of the function with the object instance a bound as the first argument to the function. foo expects 2 arguments, while a.foo only expects 1 argument.
a is bound to foo. That is what is meant by the term "bound" below:
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
With a.class_foo, a is not bound to class_foo, rather the class A is bound to class_foo.
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
Here, with a staticmethod, even though it is a method, a.static_foo just returns
a good 'ole function with no arguments bound. static_foo expects 1 argument, and
a.static_foo expects 1 argument too.
print(a.static_foo)
# <function static_foo at 0xb7d479cc>
And of course the same thing happens when you call static_foo with the class A instead.
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
Answer from unutbu on Stack Overflow@staticmethod vs @classmethod vs functions outside of class in Python - Software Engineering Stack Exchange
CLASS & STATIC METHODS
What is difference between class method and static method? (Please provide some good examples also). Thank you.
Why @classmethod and @staticmethod , why not use instance only ???
Videos
Maybe a bit of example code will help: Notice the difference in the call signatures of foo, class_foo and static_foo:
class A(object):
def foo(self, x):
print(f"executing foo({self}, {x})")
@classmethod
def class_foo(cls, x):
print(f"executing class_foo({cls}, {x})")
@staticmethod
def static_foo(x):
print(f"executing static_foo({x})")
a = A()
Below is the usual way an object instance calls a method. The object instance, a, is implicitly passed as the first argument.
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>, 1)
With classmethods, the class of the object instance is implicitly passed as the first argument instead of self.
a.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)
You can also call class_foo using the class. In fact, if you define something to be
a classmethod, it is probably because you intend to call it from the class rather than from a class instance. A.foo(1) would have raised a TypeError, but A.class_foo(1) works just fine:
A.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)
One use people have found for class methods is to create inheritable alternative constructors.
With staticmethods, neither self (the object instance) nor cls (the class) is implicitly passed as the first argument. They behave like plain functions except that you can call them from an instance or the class:
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
Staticmethods are used to group functions which have some logical connection with a class to the class.
foo is just a function, but when you call a.foo you don't just get the function,
you get a "partially applied" version of the function with the object instance a bound as the first argument to the function. foo expects 2 arguments, while a.foo only expects 1 argument.
a is bound to foo. That is what is meant by the term "bound" below:
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
With a.class_foo, a is not bound to class_foo, rather the class A is bound to class_foo.
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
Here, with a staticmethod, even though it is a method, a.static_foo just returns
a good 'ole function with no arguments bound. static_foo expects 1 argument, and
a.static_foo expects 1 argument too.
print(a.static_foo)
# <function static_foo at 0xb7d479cc>
And of course the same thing happens when you call static_foo with the class A instead.
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
A staticmethod is a method that knows nothing about the class or instance it was called on. It just gets the arguments that were passed, no implicit first argument.
A classmethod, on the other hand, is a method that gets passed the class it was called on, or the class of the instance it was called on, as first argument. This is useful when you want the method to be a factory for the class: since it gets the actual class it was called on as first argument, you can always instantiate the right class, even when subclasses are involved. Observe for instance how dict.fromkeys(), a classmethod, returns an instance of the subclass when called on a subclass:
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
If your method calls a static method on the class, then it does require information on the class. You have a class method, not a static method. By declaring it @classmethod (and adding the cls parameter), you not only properly inform the reader, you allow polymorphism. An inheritor can reimplement the called static method and change behavior.
Python's static methods are intended for methods that are part of a class, and can be called as either a class method or an instance method: both Class.the_method() and self.the_method() would work. When the static method is called, it is not given an implicit first argument:
class Example:
def instance_method_example(self, arguments):
...
@classmethod
def class_method_example(cls, arguments):
...
@staticmethod
def static_method_example(arguments):
...
If you merely want to create a helper function that is used within your class, do not use @staticmethod. Define a free function outside of the class. For example:
class Example:
def some_method(self, argument):
return _helper(argument, self.x)
def _helper(a, b):
...
The background of static methods in Python is the following: when you access an attribute of an object x.attribute or getattr(x, 'attribute'), then this name is looked up in the instance dict or the class dict. If an object is found in the class dict, it is checked whether that object is a “descriptor”: an object that describes how this attribute behaves, not an object that would be directly returned. Descriptors have dunder-methods like __get__, __set__, and __del__ that are invoked depending on whether the descriptor is accessed, assigned to, or deleted with the del operator.
Functions – the things you declare with def – are descriptors. By default, the __get__ descriptor binds the function to the instance argument (typically called self) and returns the bound function, so that it can be invoked as a method. But the various decorators change this behaviour:
- a
@classmethod defbinds to the class object, not the instance - a
@staticmethod defdoes not bind to any object and just returns the underlying function directly - a
@propertyinvokes the underlying function to retrieve a value
These differences are (partially) visible when looking at the repr() of the bound methods. With the first Example class:
instance_method_example- with class:
Example.instance_method_example
is<function Example.instance_method_example at 0x7f1dfdd6fd30>,
the unbound function - with instance:
<function Example.instance_method_example at 0x7f1dfdd6fd30>
is<bound method Example.instance_method_example of <__main__.Example object at 0x7f1dfdddcb80>>,
a method bound to the instance
- with class:
class_method_example- with class:
Example.class_method_example
is<bound method Example.class_method_example of <class '__main__.Example'>>,
a method bound to the class - with instance:
Example().class_method_example
is<bound method Example.class_method_example of <class '__main__.Example'>>,
also a method bound to the class
- with class:
static_method_example- with class:
Example.static_method_example
is<function Example.static_method_example at 0x7f1dfdd6fe50>,
the unbound function - with instance:
Example().static_method_example
is<function Example.static_method_example at 0x7f1dfdd6fe50>,
also the unbound function
- with class:
As a table:
| invoked on… | no decorator | @classmethod |
@staticmethod |
|---|---|---|---|
| … instance | bound to instance | bound to class | unbound |
| … class | unbound | bound to class | unbound |
Hello everyone,
I was studying OOP and the concept of instances, class methods and static methods still confuses me.
I have watched tons of YouTube already but I can't find a person who explains it as dumb as possible because that is how I understand things.
Please if there is anyone who can recommend to me a video or explain it to me in the simplest way possible with examples, I will be glad :)
Note: I want the simplest form of explanation about the matter.
Title says it all.
Hy Everyone,
My way of learning things is asking WHY any feature is there in any language. When I searched why for classmetohd and staticmethod in python. I found out how to use it and some intuition but not a clear answer. Please help me to understand it better.