Python knows it: Classethod and Staticmethod methods

Explain one

Generally speaking, to use a method of a class, you need to instantiate an object before calling a method.  
Using @static method or @class method, you can call directly the class name. method name () without instantiation.  
This is good for organizing the code, putting some functions that should belong to a class into that class, and also for the cleanliness of the namespace.

Since both @staticmethod and @classmethod can be called directly by the class name, what's the difference between them?
In terms of their use,

  • @ staticmethod does not need to represent the self of its own object and the cls parameters of its own class, just as it does with functions.
  • @ The class method also does not need the self parameter, but the first parameter needs to be the cls parameter representing its own class.

    If you want to call some attribute methods of this class in @static method, you can only call directly the class name, attribute name or class name, method name.  
    Because @classmethod holds cls parameters, it can call class attributes, class methods, instantiated objects, etc. to avoid hard coding.  
    The code below.

class A(object):  
    bar = 1  
    def foo(self):  
        print 'foo'  

    @staticmethod  
    def static_foo():  
        print 'static_foo'  
        print A.bar  

    @classmethod  
    def class_foo(cls):  
        print 'class_foo'  
        print cls.bar  
        cls().foo()  
###implement  
A.static_foo()  
A.class_foo()  

output

static_foo
1
class_foo
1
foo

Explanation two

The most commonly used method in classes is the instance method, that is, the method by which an instance is used as the first parameter.  
For example, a basic example method is the following:

class Kls(object):
    def __init__(self, data):
        self.data = data
    def printd(self):
        print(self.data)
ik1 = Kls('arun')
ik2 = Kls('seema')
ik1.printd()
ik2.printd()

This gives the following output:

arun
seema

 
Then take a look at the code and sample pictures:

  • 1,2 parameters are passed to the method.
  • The self parameter points to the current instance itself.
  • 4 We don't need to pass the instance itself to the method. The Python interpreter does this by itself.

What if we want to write some methods that only interact with classes instead of instances? We can write a simple way to do this outside of classes, but this diffuses the relationship between class code and the outside of class definition.

def get_no_of_instances(cls_obj):
    return cls_obj.no_inst
class Kls(object):
    no_inst = 0
    def __init__(self):
        Kls.no_inst = Kls.no_inst + 1
ik1 = Kls()
ik2 = Kls()
print(get_no_of_instances(Kls))

Output:

2

@classmethod 
We want to write a method that runs only in classes and not in instances. If we want the method to not run in instances, we can do this:

def iget_no_of_instance(ins_obj):
    return ins_obj.__class__.no_inst
class Kls(object):
    no_inst = 0
    def __init__(self):
    Kls.no_inst = Kls.no_inst + 1
ik1 = Kls()
ik2 = Kls()
print iget_no_of_instance(ik1)

output

2

After Python 2.2, you can use the @classmethod decorator to create class methods.

class Kls(object):
    no_inst = 0
    def __init__(self):
        Kls.no_inst = Kls.no_inst + 1
    @classmethod
    def get_no_of_instance(cls_obj):
        return cls_obj.no_inst
ik1 = Kls()
ik2 = Kls()
print ik1.get_no_of_instance()
print Kls.get_no_of_instance()

Output:

2
2

The advantage is that whether this method is called from an instance or from a class, it passes the class over with the first parameter.
@staticmethod 
There are often functions related to classes but static methods are needed at runtime without the participation of instances and classes. For example, changing environment variables or modifying attributes of other classes can be used for static methods. This situation can be solved directly by functions, but it also diffuses code within classes, causing maintenance difficulties.
For example:

IND = 'ON'
def checkind():
    return (IND == 'ON')
class Kls(object):
     def __init__(self,data):
        self.data = data
def do_reset(self):
    if checkind():
        print('Reset done for:', self.data)
def set_db(self):
    if checkind():
        self.db = 'new db connection'
        print('DB connection made for:',self.data)
ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()

Output:

Reset done for: 12
DB connection made for: 12

If you use @static method, you can put the relevant code in the corresponding place.

IND = 'ON'
class Kls(object):
    def __init__(self, data):
        self.data = data
    @staticmethod
    def checkind():
        return (IND == 'ON')
    def do_reset(self):
        if self.checkind():
            print('Reset done for:', self.data)
    def set_db(self):
        if self.checkind():
            self.db = 'New db connection'
        print('DB connection made for: ', self.data)
ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()

Output:

Reset done for: 12
DB connection made for: 12

Here's a more comprehensive code and illustration to show the differences between the two approaches.
@ The difference between static method and @classmethod

class Kls(object):
    def __init__(self, data):
        self.data = data
    def printd(self):
        print(self.data)
    @staticmethod
    def smethod(*arg):
        print('Static:', arg)
    @classmethod
    def cmethod(*arg):
        print('Class:', arg)

>>> ik = Kls(23)
>>> ik.printd()
23
>>> ik.smethod()
Static: ()
>>> ik.cmethod()
Class: (<class '__main__.Kls'>,)
>>> Kls.printd()
TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)
>>> Kls.smethod()
Static: ()
>>> Kls.cmethod()
Class: (<class '__main__.Kls'>,)

Keywords: Attribute Python

Added by DanielStead on Fri, 17 May 2019 14:34:58 +0300