Python staticmethod classmethod 普通方法 类变量 实例变量 cls self 概念与区别

类变量

1、需要在一个类的各个对象间交互,即需要一个数据对象为整个类而非某个对象服务。
2、同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。
3、有独立的存储区,属于整个类。
 
在python中是这样使用的:
class MyClass():
        cls_count = 0

实例变量

1、当一个类实例化成特定对象后,在该对象命名空间的变量,只有该实例对象可以访问修改
在python中是这样使用的:
class MyClass():
      def __init__(self):
            self.count = 0
 
cls:python中约定成俗的代表类本身的变量
self:python中约定成俗的代表类实例本身的变量
 
classmethod
python中的语法糖,将一个方法定义在一个类的命令空间中,可以通过cls访问类变量,但不能访问实例变量
 
staticmethod
python中的语法糖,将一个方法定义在一个类的命名空间中,
和类方法差别不大,他们的主要差别是在类方法内部的时候,类方法可以有cls的类引用,静态访问则没有,如果静态方法想使用类变量,只能硬编码类名
 
下面是一个混合使用的例子,可以观察输出,判断他们之间的不同
class demo():
    cls_count = 0

    def __init__(self):
        self.count = 0
        print self, '  instance is created'

    @classmethod
    def cls_add_class_count(cls):
        print 'classmethod before: demo count is: ', cls.cls_count
        cls.cls_count = cls.cls_count + 1
        print 'classmethod after: demo count is: ', cls.cls_count
        
    @staticmethod
    def static_add_class_count():
        print 'staticmethod before: demo count is: ', demo.cls_count
        demo.cls_count = demo.cls_count + 1
        print 'staticmethod after: demo count is: ', demo.cls_count

    def instance_add_class_count(self):
        print 'instance befor: demo count is: ', self.cls_count
        self.cls_count = self.cls_count + 1
        print 'instance after: demo count is: ', self.cls_count

    def instance_add_instance_count(self):
        print 'instance befor: instance count is: ', self.count
        self.count = self.count + 1
        print 'instance after: instance count is: ', self.count


if __name__ == '__main__':
    d1 = demo()
    d2 = demo()
    print 'call classmethod'
    d1.cls_add_class_count()
    d2.cls_add_class_count()
    print demo.cls_count
    print '----------------'
    print 'call staticmethod'
    print 'staticmethod'
    d1.static_add_class_count()
    d2.static_add_class_count()
    print demo.cls_count
    print '----------------'
    print 'call instance add class count method'
    d1.instance_add_class_count()
    d2.instance_add_class_count()
    print '----------------'
    print 'call instance add instance count method'
    d1.instance_add_instance_count()
    d2.instance_add_instance_count()

输出为:

<__main__.demo instance at 0x00000000022A9B48>   instance is created
<__main__.demo instance at 0x00000000022A9B88>   instance is created
call classmethod
classmethod before: demo count is:  0
classmethod after: demo count is:  1
classmethod before: demo count is:  1
classmethod after: demo count is:  2
2
----------------
call staticmethod
staticmethod
staticmethod before: demo count is:  2
staticmethod after: demo count is:  3
staticmethod before: demo count is:  3
staticmethod after: demo count is:  4
4
----------------
call instance add class count method
instance befor: demo count is:  4
instance after: demo count is:  5
instance befor: demo count is:  4
instance after: demo count is:  5
----------------
call instance add instance count method
instance befor: instance count is:  0
instance after: instance count is:  1
instance befor: instance count is:  0
instance after: instance count is:  1
 

总结

1 staticmethod,classmethod和实例方法都可以访问到类变量,但是,staticmethod通过类名访问,classmethod通过传入的cls访问,两者

都直接通过类本身直接调用。而实例方法需要类实例化,先在实例变量中查找,如果找不到,再到类变量中访问。

2 也就是说实例方法可以实现staticmethod和classmethod的效果,但是使用staticmethod和classmethod可以从代码上直接说明该方法的作用

posted @ 2017-07-29 17:11  yihailin  阅读(1666)  评论(0编辑  收藏  举报