2

这是我的第一个问题,所以我希望我不会一次扔太多东西。我正在为吸尘器世界问题实施四种不同的算法。到目前为止,我制作了四个不同的工作 .py 文件,但我想我会让它变得更漂亮,因为重复了很多代码,并在一个具有良好类层次结构的文件中实现它们。所以起初我有一个 Node 类,它看起来有点像这样,并且对于每种算法(广度优先、A*、贪婪和随机)都有所不同:

class Node(object):
def __init__(self, parent, depth, cost, plan):
    plana = copy.deepcopy(plan)
    self.parent = parent
    self.succsor = []
    self.depth = depth
    self.cost = cost
    self.position = []
    self.plansza = plana
# 'plansza' is an object which is a representation of state - e.g. board with marked uncleaned rooms
    self.action = ''
def printa(self):
    return [self.action]
def isFirst(self):
    res = (self.plansza.side/2)
    self.position = [res,res]
def clean(self):
    n = Node(self, self.depth+1, self.cost+1, self.plansza)
    n.position = self.position
    no = n.plansza.board
    no[n.position[0]][n.position[1]] = '.'  
    n.action = 'clean'  
    self.succsor.append(n)
def up(self):
    # // self.action = 'up'
    n = Node(self,self.depth+1,self.cost+1, self.plansza)
    n.position = [self.position[0]-1, self.position[1]]
    n.action = 'up'
    self.succsor.append(n)

#couple of other move methods...

def expand(self):
    pos = self.position 
    self.none()
    if (pos[0]>0):
        self.up()
    if (pos[1]>0):
        self.left()         
    if (pos[1] + 1 < self.plansza.side):
        self.right()
    if (pos[0] + 1 < self.plansza.side):
        self.down()
    if self.plansza.board[pos[0]][pos[1]] == 'x':
        self.clean()
    return self.succsor

现在我正在尝试使用 super() 函数来定义一个名为 NodeStar 的 Node 子类(用于 A* 实现):

class NodeStar(Node):
def __init__(self, parent, depth, cost, plan):
    super(NodeStar,self).__init__(parent, depth, cost, plan)
    self.heur = self.funH()
    self.prior = self.cost + self.heur
def expand(self):
super(NodeStar,self).expand()

其中'self.heur'、'self.funH()'和'self.prior'是Node类没有的属性和函数。此代码不起作用。我收到一个错误:

line 211, in treeSearch
for item in exp:
TypeError: 'NoneType' object is not iterable

(侧面的概念:)我不知道为什么我必须在 super() 函数中使用参数,即使我在我的计算机上安装了 python 3.4.3(我在 Sublime Text 3 中使用 Anaconda 工作)

我发现问题与 TreeSearch 函数有关,其中在边缘的第一个节点上调用了 expand() 函数。

但我主要关心的是——这是一个好的方向吗?如果是这样,我应该如何使用 super() 函数?例如,如果我需要相同的方法但返回不同的返回值,我能找到 super() 有用吗?或者,在这种情况下,我应该覆盖整个事情吗?或者我是否应该尝试在 Node 类中创建一些布尔属性来更改 Node 的类型,而不是覆盖方法(不会节省很多代码)?

我希望这不会太长。将非常感谢任何想法和想法

4

1 回答 1

0

你必须返回结果expand

def expand(self):
    return super(NodeStar,self).expand()

如果类的expand方法和NodeStar类的方法完全一样,Node就不需要在类中重新定义方法NodeStar(这是面向对象编程的继承部分)。但是,如果该NodeStar expand方法可以与原始方法的功能一起执行一些附加功能,expand那么您可以重新定义它并super.expand根据需要调用(这是面向对象编程的多态性部分)

至于你的其他问题:

面向对象编程提供了一些基本概念,例如:

  1. 继承/扩展(DRY,不要重复自己)
  2. 多态性(多方面功能的类似接口)
  3. 封装(仅使接口可见,而底层实现可以根据需要进行更改)

因此,这些原则在许多情况下肯定会有所帮助。您尝试用您的代码实现的 OO 模式是所谓的复合模式的变体,请查看它以获取更多信息和示例

实际上,这composite design pattern是一种以统一方式处理单个项目和项目组合的方法。这就是您(尝试)对Node类(单个项目)和NodeStar类(复合项目,项目序列Node)所做的事情

于 2015-05-18T23:23:30.303 回答