Detailed explanation of @staticmethod and @classmethod in python

1. The difference between @staticmethod and @classmethod

Generally speaking, to use a method of a certain class, you need to instantiate an object and then call the method.
Using @staticmethod or @classmethod, you can directly call the class name. method name () without instantiation.
This is conducive to organizing the code, putting certain functions that should belong to a certain class into that class, and at the same time conducive to the cleanliness of the namespace.
Since both @staticmethod and @classmethod can be called directly by class name. method name (), what is the difference between them?

From the point of view of their use
1, @staticmethod does not need to represent the self of its own object and the cls parameter of its own class, just like using a function.
2. @classmethod 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 @staticmethod, you can only directly class name, attribute name or class name. method name .
Since @classmethod holds cls parameters, it can call class attributes, class methods, instantiate objects, etc., to avoid hard coding.

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()  

A.static_foo()  
A.class_foo()  

'''
结果:
static_foo
1
class_foo
1
foo
'''

2. Detailed explanation

The most commonly used method in the class is the instance method, that is, the method that passes the instance as the first parameter.
For example, a basic instance method is as follows:

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()

'''
结果:
arun
seema
'''

Insert picture description here
Then take a look at the code and sample pictures:

1, 2 parameters are passed to the method.
3 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 will do these operations itself

What if we want to write some methods that only interact with the class instead of the instance? We can write a simple method outside the class to do this, but doing so will spread the relationship between the class code and the class definition Outside. If you write like the following, it will cause difficulties in code maintenance in the future:

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))

#结果:2

@classmethod
we want to write a method that only runs in the class and not in the instance. If we want the method to not run in the instance, 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)

#结果: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()

'''
结果:
2
2
'''

The advantage of this is: No matter whether this method is called from an instance or from a class, it uses the first parameter to pass the class.
@staticmethod
often has some functions related to the class but does not require the instance and class at runtime. In the case of participation, static methods are required. For example, static methods can be used to change environment variables or modify the properties of other classes. This situation can be solved directly with functions, but this will also spread the code inside the class and cause 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 @staticmethod, you can put the relevant code in the corresponding position.

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

Below is a more comprehensive code and diagram to show the difference between the two methods
@staticmethod 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'>,)

Insert picture description here

Guess you like

Origin blog.csdn.net/yjh_SE007/article/details/105750889