python staticmethod和classmethod的区别

python中有三种方法,实例方法、静态方法(staticmethod) 和 类方法(classmethod)

class A():
    method = 'class'

    #实例方法
    def normethod(self):
        print('I am the normal method')

    #静态方法
    @staticmethod
    def stamethod():
        print ('I am the static method')

    #类方法
    @classmethod
    def clsmethod(cls):
        print (f'I am the {cls.method} method')

实例方法第一个参数是 self,它表示实例化后类的地址id,所以需要一个类的实例,才能调用这个函数

>>> A.normethod()  #直接这样调用会报错
>>> a = A()
>>> a.normethod()  #需要实例化后传递进 id 参数才能调用
I am the normal method

静态方法类似普通函数,参数里面不用传递 self。有一些方法和类相关,但是又不需要类中的任何信息,出于对代码的理解和维护,就可用使用静态方法。

>>> A.stamethod()   #静态方法不用实例化可直接调用
I am the static method
>>> a = A()
>>> a.stamethod()   #也可以实例化后再调用
I am the static method

静态方法最大的优点是能节省开销,因为它不会绑定到实例对象上,它在内存中只生成一个。

>>> a1 = A()
>>> a2 = A()
>>> a1.stamethod
<function static at 0x0000000004938E48>
>>> a2.stamethod
<function static at 0x0000000004938E48>
>>> A.stamethod
<function static at 0x0000000004938E48>
>>> 
>>> a1.stamethod is A.stamethod and a2.stamethod is A.stamethod
True

而实例方法每个实例对象都是独立的,开销较大

>>> a1.normethod
<bound method A.norstatic of <__main__.A instance at 0x0000000004590AC8>>
>>> a2.normethod
<bound method A.norstatic of <__main__.A instance at 0x00000000045901C8>>
>>> a1.normethod is a2.normethod
False

而类方法与实例方法类似,但是类方法传递的不是实例,而是类本身。当需要和类交互而不需要和实例交互时,就可以选择类方法。

>>> A.clsmethod()    #类方法不用实例化可直接调用
I am the class method
>>> a = A()
>>> a.clsmethod()    #也可以实例化后再调用
I am the class method

总结
1.静态方法和类方法都可以通过类直接调用,也可以实例化后再调用

2.类方法的第一个参数是 cls,可以调用类的属性和方法,而静态方法不用传递参数,也不能调用类属性

3.如果一个方法没有使用到类本身任何变量,可以直接使用静态方法。静态方法放到类外边也不影响,主要是放在类里面给它一个作用域,方便管理

转载:

https://zhuanlan.zhihu.com/p/389770470