Python基础编程(九)魔法方法、属性和迭代器
在Python中,有的名称会在前面和后面都加上两个下划线。
在Python中,由这些名字组成的集合所包含的方法称为魔法(或称特殊)方法。
9.2 构造方法
构造方法代表着以前例子中使用过的init的初始化方法。但构造方法和其他普通方法不同的地方在于,当一个对象被创建后,会立即调用构造方法。
class Foobar: def __init__(self): self.aomevar = 42 >>>f = Foobar() >>>f.somevar 42
9.2.1 重写一般方法和特殊的构造方法
重写是继承机制中的一个重要内容,对于构造方法尤其重要。构造方法用来初始化新创建对象的状态,大多数子类不仅要拥有自己的初始化代码,还要拥有超累的初始化代码。
如果一个类的构造方法被重写,那么需要调用超类的构造方法,否则对象可能不会被正确的初始化。
考虑下面的Bird类:
class Bird: def __init__(self) self.hungry = True def eat(self): if self.hungry: print 'Aaaah...' self.hungry = False else: print 'No, thanks!'
>>> b = Bird() >>> b.eat() Aaaah... >>> b.eat() No, thanks!现在考虑子类SongBird:
class SongBird(Bird) def __init__(self): self.sound = 'Aquawk!' def sing(self): print self.sound
>>> ab = SongBird() >>> sb.sing() Squawk!尝试在SongBird中调用eat方法sb.eat(),就会产生一个问题:
异常说明了错误,SongBird没有hungry特性,原因:在SongBird中,构造方法被重写,担心的构造方法没有任何关于初始化hungry特性的代码。
为了达到预期效果,SongBird的构造方法必须调用其超类Bird的构造方法来确保进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定函数,或者使用super函数。
9.2.2 调用未绑定的超类构造函数
class SongBird(Bird): def __init__(self): Bird.__init__(self) self..sound = 'Squawk!' def sing(self): print self.sound只添加了一行代码——Bird.__init__(self)。
>>> sb = SongBird() >>> sb.sing() Squawk! >>> sb.eat() Aaaah... >>> sb.eat() No, thanks!在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(绑定方法),但如果直接调用类的方法(比如Bird.__init__),那么就没有实力会被绑定,这样就可以自由的提供需要的self参数。称为未绑定方法。
9.2.3 使用super函数
class SongBird(Bird): def __init__(self): super(SoundBird.self).__init__() self..sound = 'Squawk!' def sing(self): print self.sound
结果如上面的方法。
9.3 成员访问
基本的序列和映射的规则很简单,但是如果要实现它们全部功能就需要实现很多魔法函数。
9.3.1 基本的序列和映射规则
class ArithmeticSequence: def __init__(self,start=0,step=1): self.start = start self.step = step self.changed = ( ) def __get__(self,key) checkIndex(key) try: return self.changed[key] except KeyError: return self.start + key*self.strp def __setitem__(self,key,value) checkIndex(key) self.changed[key] = value这里实现的是一个算数序列,该序列的每个元素都比它前面的元素大一个常数。
>>> s = ArithmeticSequense(1,2) >>> s[4] 9 >>> s[4] = 2 >>> s[4] 2 >>> s[5] 11注意观察结果是怎么实现的。↑
__len__(self):这个方法应该返回集合中所有项目的数量。对于序列来说,这就是元素的个数;对于映射来说,则是键-值对。
__getitem__(self,key):这个方法返回所给键对应的值。
__setitem__(self,key,value):这个方法应该按一定的方式存储和key相关的value。
__delitem__(self,key):这个方法在对一部分对象使用del语句是被调用,同时必须删除和元素相关的键。