粗解python的@classmethod和@staticmethod及普通实例方法

时间:2022-11-22 08:22:39

引言:

  使用不同的函数定义方法,可以使得函数定义更加有效而且易于维护

  本文为博主原创,根据本人自己的理解整理而成,若有不准确的地方,希望能留言告知以免误导他人;

  首先进一段代码,来直观感受一下不同类型的函数的定义方法:

>>>
>>> class A(object):
    a =
    def instance_method(self):
        print '实例方法打印类变量a: %s' % self.a
    @classmethod
    def class_method(cls):
        print '类方法打印类变量a: %s' % cls.a
    @staticmethod
    def static_method(b):
        print '静态方法打印自己的变量b: %s' % b

>>>
>>> A.instance_method()

Traceback (most recent call last):
  File , in <module>
    A.instance_method()
TypeError: unbound method instance_method() must be called with A instance as first argument (got nothing instead)
>>>
>>> A().instance_method()
实例方法打印类变量a:
>>>
>>> A.class_method()
类方法打印类变量a:
>>>
>>> A().class_method()
类方法打印类变量a:
>>>
>>> A.static_method()
静态方法打印自己的变量b:
>>>
>>> A().static_method()
静态方法打印自己的变量b:
>>>
>>> 

  解析一下以上代码:

  1.实例方法instance_method()的定义不需要声明,默认需要一个self参数作为第一个参数;在调用的时候这个self参数指代实例对象;由代码中的调用方式可以看出,实例方法不能用类对象调用,也就是A.instance_method()调用会报错;但是可以用实例对象A().instance_method()调用;当然如果不明确,可以写成:

      ins = A()

      ins.instance_method()

  2.类方法class_method()需要用装饰器@classmethod来声明,默认需要一个cls参数作为函数的第一个参数;在调用的时候这个cls参数指代类对象;这样定义的好处是不需要实例化类对象即可调用这个方法:A.instance_method();当然如果需要,类方法也可以通过实例对象调用:A().class_method();但是在大多别的变成语言中不允许实例对象调用类方法;类方法的调用在导入模块时能得到更好的体现:

      import A

      A.class_method()

  3.静态方法static_method()需要用装饰器@staticmethod来声明,理解静态变量的最好方法是把静态方法拿到类的外面,或者说重新再类的外面定义一个相同的函数来对比两者的区别;其实静态变量就是在类中定义的跟这个类没有关系的方法,它不引用类的变量,也跟类中的其他函数没有关联,完全自己玩自己的,所以能够看到在代码中定义静态变量的时候给了它自己的一个函数变量b,而它打印的也是自己的变量b;但是既然定义在类中,就得通过类对象或者实例对象来调用;

  另外,需要注意得是,实例方法和类方法中的self和cls这两个字符本身没有什么特殊,完全可以用别的字符如hello或者hi来代替,但是python中约定俗成默认用self和cls来作为实例方法和类方法的第一个参数,在调用方法时,self用来指代实例对象,cls用来指代类对象本身;静态方法因为本身与类中其他变量或者方法没有关联,所以不需要这样一个参数;