实例属性和类属性

实例属性

  实例仅拥有数据属性(方法严格来说是类属性),后者只是与某个类的实例相关联的数据值,并且可以通过句点属性标识法来访问。这些值独立于其它实例或类。当一个实例被释放后,它的属性 同时也被清除了。

【1】“实例化”实例属性

  设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行。构造器__init()__是设置这些属性的关键点之一。 

  python能够在“运行时”创建实例属性 。

  Python 不仅是动态类型,而且在运行时,允许这些对象属性的动态创建。 

  假如属性在条件语句中创建,如果该条件语句块并未被执行,属性也就不存在,而你 在后面的代码中试着去访问这些属性,就会有错误发生。 

class People:
    #类属性
    address = "广东"
    def __init__(self):
        #实例属性
        self.name = "hugo"
        self.age = 18

p = People()
#修改实例属性
p.age = 19
print(p.address)
#广东
print(p.name)
#hugo
print(p.age)
#19

print(People.address)
#广东
print(People.name)
#报错
print(People.age)
#报错

 

【2】查看实例属

  内建函数dir()可以显示类属性,同样还可以显示所有实例属性

class C:
    pass
c = C()
c.foo = "FOO"
c.bar = "BAR"
print(dir(c))

'''
['__class__', '__delattr__', '__dict__',
'__dir__', '__doc__', '__eq__', 
'__format__','__ge__', '__getattribute__',
'__gt__', '__hash__','__init__',
'__init_subclass__', '__le__', '__lt__',
'__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', 
'__subclasshook__', '__weakref__', 'bar', 'foo']
'''

  实例中一个特殊属性__dict__,它是实例属性构成的一个字典

print(c.__dict__)
#{'foo': 'FOO', 'bar': 'BAR'}

【3】内建类型属性

  内建类型有实例属性和类属性

x = 1+2j
print(x.__class__)
#<class 'complex'>
print(dir(x))
'''
['__abs__', '__add__', '__bool__', 
'__class__', '__delattr__', '__dir__', 
'__divmod__', '__doc__', '__eq__', 
'__float__', '__floordiv__', '__format__', 
'__ge__', '__getattribute__', '__getnewargs__', 
'__gt__', '__hash__', '__init__', 
'__init_subclass__', '__int__', '__le__', 
'__lt__', '__mod__', '__mul__', 
'__ne__', '__neg__', '__new__', 
'__pos__', '__pow__', '__radd__', 
'__rdivmod__', '__reduce__', '__reduce_ex__', 
'__repr__', '__rfloordiv__', '__rmod__', 
'__rmul__', '__rpow__', '__rsub__', 
'__rtruediv__', '__setattr__', '__sizeof__', 
'__str__', '__sub__', '__subclasshook__', 
'__truediv__', 'conjugate', 'imag', 'real']
'''

#访问它的数据属性
print(x.imag)
#2.0
print(x.real)
#1.0
print(x.conjugate())
#(1-2j)

#print(x.__dict__)
#报错,内建类型中不存在这个属性

 

【4】实例属性和类属性

  类属性仅是与类相关的数据值,和实例属性不同,类属性和实例无关。这些值像静态成员那样被引用,即使在多次实例化中调用类, 它们的值都保持不变。不管如何,静态成员不会因为实例而改变它们的值,除非实例中显式改变它们的值。

  类和实例都是名字空间。类是类属性的名字空间,实例则是实例属性的。

  关于类属性和实例属性,还有一些方面需要指出。你可采用类来访问类属性,如果实例没有同 名的属性的话,你也可以用实例来访问。

  访问类属性

    访问属性,首先会在实例中去搜索,然后是类,再然后就是从继承树中的基类。

class C:
    bar = "BAR"
c = C()
#通过类来访问属性
print(C.bar)
#BAR
#通过实例来访问属性
print(c.bar)
#BAR

#只能通过类来更新
C.bar = C.bar + "FOO"
print(C.bar)
#BARFOO
#实例访问它,其值已经改变
print(c.bar)
#BARFOO


# c.bar = c.bar + "GOO"
# print(C.bar)
#BAR
# print(c.bar)
#BARGOO

 注意:

  任何对实例属性的赋值都会创建一个实例属性(如果不存在的话)并且对其赋值。如果类属性中存在同名的属性,有趣的副作用即产生。

class Bar:
    x = 1
bar = Bar()
print(bar.x)
#1
bar.x = 2
print(bar.x)
#2
print(Bar.x)
#1
#总结:没有变,只是创建了一个新的实例属性,覆盖了对类属行的引用。类属性并没有受到影响

#删除实例属性,仍然能够访问到类属性
del bar.x
print(bar.x)
#1

 

总结: 

  

  • 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性

posted @ 2018-03-26 00:29  今晚打老虎i2016  阅读(547)  评论(0编辑  收藏  举报