一、简介
类属性:类属性仅与其被定义的类相绑定,类属性仅当需要有更加“静态”数据类型时才变得有用,它和任何实例都无关,如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)若有建议,请留言,在此先感谢!