上节老猿介绍了实例变量的访问方法,本节结合一个具体案例详细介绍实例变量访问。
本节定义一个Vehicle类(车),它有三个实例变量self.wheelcount(轮子数)、self.power(动力)、self.totaldistance(累计行驶里程),但在构造方法内只定义了前2个,第3个在其他实例方法中访问。一、类定义
class Vehicle():
def __init__(self,wheelcount, power):
self.wheelcount,self.power = wheelcount,power
#构造方法只定义了self.wheelcount,self.power两个实例变量。
def drive(self,distance):
try:self.totaldistance += distance
except: self.totaldistance = distance
#drive方法中要根据一次行驶距离计算总行驶里程,但self.totaldistance没有在构造方法定义,因此在drive方法内采用了一个异常处理,确保该实例变量未定义时会执行定义,当然在构造函数内初始化定义该变量是最好的。
def gettotaldistance(self):
if not hasattr(self,'totaldistance'): self.totaldistance=0;
return self.totaldistance
#类似drive方法,在gettotaldistance内判断实例是否有'totaldistance'存在,以便对一个未定义的实例变量进行初始化防止程序出错
二、实例化对象及实例变量的访问
我们定义两个实例对象马车和汽车:
hippomobile = Vehicle(2,'马')
car=Vehicle(4,'汽油发动机')
为了方便观察对象的属性,我们定义一个函数dirp取代dir,该函数是将dir返回的带两个下划线开头的属性和方法剔除,因为带两个下划线的属性和方法要么是私有的(双下划线开头,不是双下划线结尾),要么是特殊变量(特殊变量必须以双下划线开头和结尾),特殊变量是可以直接访问的,但因为从Object类继承过来的特殊属性太多,不利于观察自己定义属性,因此剔除:
def dirp(iter): return [i for i in dir(iter) if not i.startswith('__')]
我们用dirp观察hippomobile、car这2个对象的属性和方法,他们都有:
['drive', 'gettotaldistance', 'power', 'wheelcount']
此时执行:
car.oil=0
truck=(4,'汽油发动机')
再用dirp观察,会发现hippomobile保持不变,car多出了一个oil属性,truck的属性与hippomobile一样,可见实例增加的属性对存量对象和新定义的实例对象都不会影响,只影响该实例自身。
我们再执行:truck.drive(100),再用dirp观察,发现truck对象多了一个'totaldistance'属性,而其他对象都没有,可见这个属性是执行方法后变量赋值之后才存在,并不是实例定义之后就存在,如果要变量定义就存在,就需要在构造方法进行初始化。
通过上面案例的说明,实例属性是必须执行赋值语句之后才存在,该赋值语句要么就是实例方法中(不一定是构造方法)的代码,要么就是类体外面的访问实例的代码。
本节老猿介绍了实例变量赋值的方法,并给出了相关案例,内容比较重要但容易理解,请大家结合案例好好理解。