Python拾遗之类属性和实例属性(一)

来源:互联网 发布:数据库安装教程 编辑:程序博客网 时间:2024/06/08 09:40

关于类属性和实例属性(一)


深入理解类属性和实例属性:


下面的实例中,类Foo1在创建时,带了类属性Foo1_value,通过类对象可以访问它,例如Foo1.Foo1_value,当实例foo1被创建后,对实例foo1而言,它并没有在类里定义实例属性,所以访问会失败。python解释器会首先实例的内存空间里搜索Foo1_value,由于本身没有定义,所以没有,(此处脑补实例的类图关系),实例的内存空间里保存有创建它的类的指针,所以接下来python解释器会去创建它的类中找Foo1_value,最后在这里被找到了,如果没有,就会去这个类的继承树中的基类里去找。所以实例foo1访问的Foo1_value,类的类属性,如果此时要通过实例要修改这个类属性,python解释器会单独开辟一块空间来,创建同名的实例属性foo1.Foo1_value,此时通过实例访问(foo1.Foo1_value)的Foo1_value属性并不不是类属性,因为访问的时候Python解释器会从实例本身的名称空间里开始找,恰好找到了,也就不会去找同名的类属性了,此之谓屏蔽,直到这个实例属性被python解释器删除,这样再次访问实例属性,python解释器还是会找到类属性返回给它,注意此时的实例属性的字段和类属性的字段并不是因为引用的是同一块内存空间,也不是所谓的浅拷贝(存放这个类属性的内存空间),只要你操作的实例字段是面向类属性的,那么你对这个字段的删除操作就是直接删除这个类属性。


实例环境:

Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:40:30) [MSC v.1500 64 bit (AMD64)] on win32

实例:

#类里面没有定义实例属性>>> class Foo1(object):...     Foo1_value = 100... #类在定义后(解释器console操作下),就被载入内存中>>> Foo1.Foo1_value100>>> id(Foo1.Foo1_value)44657872L#删除后内存里的类属性将不存在,需重新载入(重复定义类的操作)>>> del Foo1.Foo1_value>>> Foo1.Foo1_valueTraceback (most recent call last):  File "<input>", line 1, in <module>AttributeError: type object 'Foo1' has no attribute 'Foo1_value'#重新将类载入内存>>> class Foo1(object):...     Foo1_value = 100... Foo1.Foo1_value100>>> id(Foo1.Foo1_value)44657872L>>> foo1 = Foo1()>>> foo1.Foo1_value100#此时这个实例的属性字段代表的就是这个类属性本身>>> id(foo1.Foo1_value)44657872L#通过类的属性字段修改,该类的属性>>> Foo1.Foo1_value += 1>>> Foo1.Foo1_value101#此时内存id虽然有变化,但实例的属性字段还是代表的类属性本身>>> id(Foo1.Foo1_value)44657848L>>> id(foo1.Foo1_value)44657848L#类属性修改会影响同名的实例属性,因为那个实例字段的属性代表的依旧是类属性本身>>> foo1.Foo1_value101>>> foo1.Foo1_value += 1#但是当通过实例的这个属性字段去更改时,python解释就会产生上述的屏蔽机制#此时如下的这两个字段的属性已不是同一块内存空间里的数值了>>> id(Foo1.Foo1_value)44657848L>>> id(foo1.Foo1_value)44657824L>>> foo1.Foo1_value102>>> Foo1.Foo1_value101#删除Python给实例创建的同名实例属性字段>>> del foo1.Foo1_value#再次访问该实例的此属性字段,python解释器又会去找类的属性>>> foo1.Foo1_value101>>> id(foo1.Foo1_value)44657848L>>> id(Foo1.Foo1_value)44657848L#类属性修改会影响同名的实例属性,类的赋值只是单纯地给名称赋值指针地址,在内存里类空间仅仅还只是一个,只是单纯地浅拷贝>>> Foo1.Foo1_value += 111>>> Foo1.Foo1_value212>>> foo1.Foo1_value212>>> foo2 = Foo1>>> foo2.Foo1_value212#但是在删除这个名称的属性字段的时候,python通过这个浅拷贝过来名称,找到了Foo1类的属性字段,并在内存里删除,此时,所有通过这个类的其他引用名称的属性字段来访问该属性,并坑定会报错>>> del foo2.Foo1_value>>> foo1.Foo1_valueTraceback (most recent call last):  File "<input>", line 1, in <module>AttributeError: 'Foo1' object has no attribute 'Foo1_value'>>> Foo1.Foo1_valueTraceback (most recent call last):  File "<input>", line 1, in <module>AttributeError: type object 'Foo1' has no attribute 'Foo1_value'#如下,在定义类的时候定义实例属性,等同于另外开辟了一块内存空间,存放自己定义的值,相对于上一个实例来说可以说是主动屏蔽>>> class Foo2(object):    Foo2_value = 100    def __init__(self):        self.Foo2_value = 5>>> Foo2.Foo2_value100>>> id(Foo2.Foo2_value)44657872L>>> foo2 = Foo2()>>> foo2.Foo2_value5>>> id(foo2.Foo2_value)44656168L#这就是单纯地浅拷贝>>> var = foo2.Foo2_value>>> var5>>> id(var)44656168L#删除的只是引用>>> del var#并不会删掉实例属性的值>>> foo2.Foo2_value5#因为“主动屏蔽”更改类属性不会影响实例属性>>> Foo2.Foo2_value += 233>>> Foo2.Foo2_value 333>>> foo2.Foo2_value5#删除同名的实例属性,屏蔽机制消逝>>> del foo2.Foo2_value>>> foo2.Foo2_value333
0 0
原创粉丝点击