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 >>>