8、魔法方法、属性和迭代器
魔法方法在特殊的情况下会被Python调用,最重要的是构造方法__init__,当对象创建时,会自动立即调用。
注:Python中还有魔法方法__del__,对象在垃圾回收前调用,但调用的具体时间不可知,建议避免使用。
子类的构造方法要再次实现超类的构造方法,来确保超类变量的初始化。有两种方法达到这个目的:调用超类构造方法的未绑定版本,或者使用super函数(3.0后版本)。
子类的__init__中Father.__init__(self);或普通方式(绑定)调用super(Son,self).__init__()。
构建序列/映射规则的四种魔法方法:__len__,__getitem__,__setitem__,__delitem__。
属性,property函数创建一个属性,其中访问器函数被作为参数,共有四个参数:fget、fset、fdel、doc,后两个可选。直接操作属性比使用访问器更方便易懂。
静态方法使用Staticmethod修饰,类方法使用Classmethod修饰。静态方法没有self参数,可被类直接调用;类方法需要名为cls的类似self的参数,但cls参数是自动绑定到类的。二者可使用装饰器的语法:@操作符。区别就在于类方法传进去了cls参数,功能是针对类的。
迭代器:__iter__方法,迭代器可应用于任何实现了__iter__和__next__方法的对象。而且在3.0中内建函数iter可以获得对象的迭代器,内建函数next可以访问__next__方法。
八皇后问题
有一个棋盘和八个要放在上面的皇后,唯一的要求是皇后之间不能形成威胁。这是一个经典的回溯问题:首先尝试放置第一个皇后,然后放置第二个,以此类推。如果发现不能放置下一个皇后,就回溯到上一步,试着将皇后放到其他位置。
首先定义状态,使用元组存储可能的解决方案,每一个元组的元素都指示相应行的皇后的位置(列)。
然后寻找冲突,将已知皇后的位置传入conflict函数,然后计算下一个位置是否会发生冲突。
def conflict(state,nextX): nextY=len(state) for i in range(nextY): if abs(state[i]-nextX) in (0, nextY-i):#在同一列或对角线上 return True return False
最后递归:
def queens(num=8,state=()): for pos in range(num): if not conflict(state,pos): if len(state)==num-1: yield(pos,) else: for result in queens(num, state+(pos,)): yield(pos,) + result >>> for solution in queens(8): print(solution) (0, 4, 7, 5, 2, 6, 1, 3) (0, 5, 7, 2, 6, 3, 1, 4) … >>> len (list(queens(8))) 92
共有92中可能的组合。