python的类属性和实例属性

一、简介

       类属性:类属性仅与其被定义的类相绑定,类属性仅当需要有更加“静态”数据类型时才变得有用,它和任何实例都无关,如class A():count = 10;。实例属性:实例仅拥有数据属性,它是与某个类的实例相关联的数据值,这些值独立于其他实例或类。当一个实例被释放后,它的属性同时也被清除了,如class A():def __init__(self):self.number = 10;同时实例属性可以在类外声明,class A():pass,a = A(),a.count = 20。

二、详解

1、Python下测试

       python的实例属性必须在__init__(self) 方法中定义(若没有定义,只是引用访问的仍是类属性),直接跟在类名后边定义的属性都默认是类属性(类似于c++的static变量)。

>>> class A:
...   count = 10;
... 
>>> a = A()
>>> b = A()
>>> print A.count #类属性可以通过类名直接引用
10
>>> print a.count, b.count  #因仅是引用,访问的是类属性
10 10
>>> a.count = 20  #定义实例属性,覆盖类属性
>>> print A.count, a.count, b.count
10 20 10
>>> A.count = -1
>>> print A.count, a.count, b.count
-1 20 -1
>>> a.__class__.count
-1

2、警示程序

(1)代码:

#encoding=utf-8
import sys
class Model():
  model_path = "class_path"
  model_dict = {'1':'linux'}
  def __init__(self, path = None):
    self.reload(path)

  def reload(self, path = None):
    if not path: return
    #self.model_dict = {}      #定义,实例属性
    self.model_dict.clear()    #没有定义,访问的是类属性
    self.model_dict['2'] = 'unix'
    self.model_path = path;

def main():
  m1 = Model();
  m2 = Model();
  print Model.model_path
  print Model.model_dict
  m1.reload("instance_m1_path")
  m2.reload("instance_m2_path")

  print '#'*15
  print m1.model_path
  print m2.model_path
  print Model.model_path

  print '#'*15
  print m1.model_dict
  print Model.model_dict
  print m2.model_dict
  print Model.model_dict
  return 0

main()

运行结果:
 

class_path
{'1': 'linux'}
###############
instance_m1_path
instance_m2_path
class_path
###############
{'2': 'unix'}
{'2': 'unix'}
{'2': 'unix'}
{'2': 'unix'}

原因:

1、self.model_path=path; #这对self.model_path进行了赋值,python中的第一次赋值视为变量的定义!

2、self.xxxx这种格式的第一次赋值含义是什么呢?–>含义是:定义,也就是说定义了一个名为xxxx的实例属性。

3、因此m1,m2的两次调用,分别定义了对应的(不同的)self.model_path属性。而self.model_dict,从头到尾都是引用它,从未进行过赋值(重定义),所以引用的都是类属性。

(2)若增加self.model_dict = {}的定义:

#encoding=utf-8
import sys
class Model():
  model_path = "class_path"
  model_dict = {'1':'linux'}
  def __init__(self, path = None):
    self.reload(path)

  def reload(self, path = None):
    if not path: return
    self.model_dict = {}       #定义,实例属性
    self.model_dict.clear()    #没有定义,访问的是类属性
    self.model_dict['2'] = 'unix'
    self.model_path = path;

def main():
  m1 = Model();
  m2 = Model();
  print Model.model_path
  print Model.model_dict
  m1.reload("instance_m1_path")
  m2.reload("instance_m2_path")

  print '#'*15
  print m1.model_path
  print m2.model_path
  print Model.model_path

  print '#'*15
  print m1.model_dict
  print Model.model_dict
  print m2.model_dict
  print Model.model_dict
  return 0

main()

运行结果:

class_path
{'1': 'linux'}
###############
instance_m1_path
instance_m2_path
class_path
###############
{'2': 'unix'}
{'1': 'linux'}
{'2': 'unix'}
{'1': 'linux'}

三、总结

(1)python的属性机制值得好好比较,这样才能防止数据的错乱。
(2)若有建议,请留言,在此先感谢!

    原文作者:乌托邦2号
    原文地址: https://blog.csdn.net/taiyang1987912/article/details/49276615
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞