In general, static methods know nothing about the class state. They are utility-type methods that take some parameters and work upon those parameters. On the other hand class methods must have class as a parameter.,A static method does not receive an implicit first argument. A static method is also a method that is bound to the class and not the object of the class. This method can’t access or modify the class state. It is present in a class because it makes sense for the method to be present in class.,A class method can access or modify the class state while a static method can’t access or modify it.,In this article, we will cover the basic difference between the class method vs Static method in Python and when to use the class method and static method in python.
Syntax Python Class Method:
class C(object):
@classmethod
def fun(cls, arg1, arg2, ...):
....
fun: function that needs to be converted into a class method
returns: a class method
for
function.
Syntax Python Static Method:
class C(object):
@staticmethod
def fun(arg1, arg2, ...):
...
returns: a static method
for
function fun.
Output:
21 25 True
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)
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)
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>>
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
>>>
A class method receives the class as implicit first argument, just like an instance method receives the instance. To declare a class method, use this idiom:
class C:
@classmethod
def f(cls, arg1, arg2, ...): ...
A static method does not receive an implicit first argument. To declare a static method, use this idiom:
class C:
@staticmethod
def f(arg1, arg2, ...): ...
To decide whether to use @staticmethod or @classmethod you have to look inside your method. If your method accesses other variables/methods in your class then use @classmethod. On the other hand, if your method does not touches any other parts of the class then use @staticmethod.
class Apple: _counter = 0 @staticmethod def about_apple(): print('Apple is good for you.') # note you can still access other member of the class # but you have to use the class instance # which is not very nice, because you have repeat yourself # # For example: # @staticmethod # print('Number of apples have been juiced: %s' % Apple._counter) # # @classmethod # print('Number of apples have been juiced: %s' % cls._counter) # # @classmethod is especially useful when you move your function to another class, # you don 't have to rename the referenced class @classmethod def make_apple_juice(cls, number_of_apples): print('Making juice:') for i in range(number_of_apples): cls._juice_this(i) @classmethod def _juice_this(cls, apple): print('Juicing apple %d...' % apple) cls._counter += 1
You may have seen Python code like this pseudocode, which demonstrates the signatures of the various method types and provides a docstring to explain each:
class Foo(object): def a_normal_instance_method(self, arg_1, kwarg_2 = None): '' ' Return a value that is a function of the instance with its attributes, and other arguments such as arg_1 and kwarg2 '' ' @staticmethod def a_static_method(arg_0): '' ' Return a value that is a function of arg_0.It does not know the instance or class it is called from. '' ' @classmethod def a_class_method(cls, arg1): '' ' Return a value that is a function of the class and other arguments. respects subclassing, it is called with the class it is called from. '' '
For example, this is an instance of a string:
', '
if we use the instance method, join
on this string, to join another iterable,
it quite obviously is a function of the instance, in addition to being a function of the iterable list, ['a', 'b', 'c']
:
>>> ', '.join(['a', 'b', 'c'])
'a, b, c'
And later we can use this as a function that already has the first argument bound to it. In this way, it works like a partial function on the instance:
>>> join_with_colons('abcde')
'a:b:c:d:e' >>>
join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF'])
'FF:FF:FF:FF:FF:FF'
An example of a static method is str.maketrans
, moved from the string
module in Python 3. It makes a translation table suitable for consumption by str.translate
. It does seem rather silly when used from an instance of a string, as demonstrated below, but importing the function from the string
module is rather clumsy, and it's nice to be able to call it from the class, as in str.maketrans
# demonstrate same function whether called from instance or not: >>> ', '.maketrans('ABC', 'abc') { 65: 97, 66: 98, 67: 99 } >>> str.maketrans('ABC', 'abc') { 65: 97, 66: 98, 67: 99 }
Static methods do not know about the class state. These methods are used to do some utility tasks by taking some parameters.,The class method takes the class as a parameter to know about the state of that class.,In this article, we learned about decorators in Python, static methods, and class methods. We learned the working of both methods. We saw key differences between the two methods and how a class defines them.,The below example shows how static and class methods work in a class. Class methods are used for factory purposes, that's why in the below code @classmethod details() is used to create a class object from a birth year instead of age. Static methods are utility functions and work on data provided to them in arguments.
Example: Static Methods
class static_example(object):
#decorator
@staticmethod
def fun(arg1, arg2, ...):
...
Example: Define Class Method
class class_example(object):
#decorator
@classmethod
def func(cls, arg1, arg2, ...):
....
The below example shows how static and class methods work in a class. Class methods are used for factory purposes, that's why in the below code @classmethod details() is used to create a class object from a birth year instead of age. Static methods are utility functions and work on data provided to them in arguments.
from datetime import date class Person: #class constructor def __init__(self, name, age): self.name = name self.age = age @classmethod def details(cls, name, year): return cls(name, date.today().year - year) @staticmethod def check_age(age): return age > 18 #Driver 's code person1 = Person('Mark', 20) person2 = Person.details('Rohan', 1992) print(person1.name, person1.age) print(person2.name, person2.age) print(Person.check_age(25))
The static methods are used to do some utility tasks, and class methods are used for factory methods. The factory methods can return class objects for different use cases.,Static methods serve mostly as utility methods or helper methods, since they can't access or modify a class's state.,In this section, we will discuss the difference between the class method and the static method. ,There is another one called instance method but inner working of instance method is the same as the class method. Actually, Python automatically maps an instance method call to a class method. For instance, a call like this:
We can check the behavior of each method regarding the first argument each method takes:
class MyClass:
def __init__(self):
pass
def normal_method( * args, ** kwargs):
print("normal_method({0},{1})".format(args, kwargs))
@classmethod
def class_method( * args, ** kwargs):
print("class_method({0},{1})".format(args, kwargs))
@staticmethod
def static_method( * args, ** kwargs):
print("static_method({0},{1})".format(args, kwargs))
obj = MyClass()
obj.normal_method()
obj.normal_method(1, 2, a = 3, b = 4)
obj.class_method()
obj.class_method(1, 2, a = 3, b = 4)
obj.static_method()
obj.static_method(1, 2, a = 3, b = 4)
normal_method((<__main__.MyClass object at 0x10d06c370>,),{})
normal_method((<__main__.MyClass object at 0x10d06c370>, 1, 2),{'a': 3, 'b': 4})
class_method((<class '__main__.MyClass'>,),{})
class_method((<class '__main__.MyClass'>, 1, 2),{'a': 3, 'b': 4})
static_method((),{})
static_method((1, 2),{'a': 3, 'b': 4})
def outside_foo():
@classmethod
def cfoo(cls, )
@staticmethod
def sfoo()
def outside_foo():
def foo(self, )
@classmethod
def cfoo(cls, )
@staticmethod
def sfoo()
>>> class Callback:
...def __init__(self, color):
...self.color = color
...def changeColor(self):
...print(self.color)
...
>>>
obj = Callback('red') >>>
cb = obj.changeColor >>>
cb()
red
>>> obj.changeColor <bound method Callback.changeColor of <__main__.Callback instance at 0x7f95ebe27f80>>
>>> Callback.changeColor
<unbound method Callback.changeColor>