13.6 实例属性
实例仅拥有数据属性(方法严格来说是类属性),后者只是与某个类的实例相关联的数据值,并且可以通过句点属性标识法来访问。这些值独立于其他实例或类。当一个实例被释放后,它的属性同时也被清楚了。
13.6.1 ”实例化“实例属性(或创建一个更好的构造器)
1. 在构造器中首先设置实例属性
构造器是最早可以设置实例属性的地方,因为__init__()是实例创建后第一个被调用的方法。
2. 默认参数提供默认的实例安装
默认参数应当是不变的对象;像列表(list)和字典(dictionary)这样的可变对象可以扮演静态数据,然后在每个地方调用中来维护它们的内容。
3. __init__()应当返回None
>>> class C(object):
... def __init__(self, par1 = 1, par2 = "2"):
... self.att1 = par1
... self.att2 = par2
... return None
...
>>> C().__dict__
{'att2': '2', 'att1': 1}
>>> c = C()
>>> (c.__class__)().__dict__
{'att2': '2', 'att1': 1}
>>>
13.6.2 查看实例属性
与类相似,实例也有一个__dict__特殊属性,它是实例属性构成的一个字典。
13.6.3 特殊的实例属性
c.__class__ 实例化c的类
c.__dict__ c的属性
13.6.4 内建类型属性
对内建类型也可以使用dir(),与任何其他对象一样,可以得到一个包含它属性名字的列表。
试着访问__dict__会失败,因为在内建类型中,不存在这个属性。
13.6.5 实例属性vs类属性
1. 访问类属性
>>> class C(object):
... attr1 = 1.0
...
>>> C.attr1
1.0
>>> c=C()
>>> c.attr1
1.0
>>> C.attr1=1.1
>>> c.attr1
1.1
>>> C.attr1
1.1
>>>
当实例c被创建后,对实例c而言,访问c.version会失败,不过Python首先会在实例中搜索名字version,然后是类,再就是继承树中的基类。
2. 从实例中访问类属性需谨慎
给一个与类属性同名的实例属性赋值,我们会有效地”隐藏“类属性,但一旦我们删除了这个实例属性,类属性又重见天日。
>>> class C(object):
... attr1 = 1
...
>>> c=C()
>>> c.attr1
1
>>> c.attr1 = 2
>>> c.attr1
2
>>> C.attr1
1
>>> del c.attr1
>>> c.attr1
1
>>> C.attr1
1
>>>
但在类属性值可变的情况下,一切又都不同了:
>>> class C(object):
... attr1 = {"1":111}
...
>>> C.attr1
{'1': 111}
>>> c=C()
>>> c.attr1["2"] = 222
>>> C.attr1
{'1': 111, '2': 222}
>>> del c.attr1
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: attr1
>>>
3. 类属性持久性
类属性的修改会影响到所有的实例。
>>> class C(object):
... attr1 = 1
...
>>> C.attr1
1
>>> C.attr1 = 2
>>> c= C()
>>> c.attr1
2
>>>