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中可能的组合。

posted @ 2013-12-17 16:50  侯凯  阅读(451)  评论(0编辑  收藏  举报