2015-05-18 6 views
2

это мой первый вопрос, поэтому я надеюсь, что не буду бросать слишком много вещей сразу. Я реализую четыре разных алгоритма для Vacuum Cleaner World problem. До сих пор я делал четыре разных рабочих файла .py, но я думал, что сделаю его более привлекательным, поскольку много кода повторяется и реализует его все в одном файле с хорошей иерархией классов. Так что сначала я был класс Node, который выглядел немного, как это и было немного отличается для каждого алгоритма (ширина-первых, A *, жадным и случайных):python 3, функция super() и наследование класса - может ли это быть сделано так?

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 

Теперь я пытаюсь использовать супер() в определении подкласса узла с именем NodeStar (для реализации *):

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 

(Notion на стороне :) Я не знаю, почему я должен использовать аргументы в супер() функцию, даже если я установил питона 3.4.3 на моем компьютере (я работаю в Sublime Text 3 с Anaconda)

Я вижу, что проблема каким-то образом связана с функцией TreeSearch, где функция expand() была вызвана в первом узле бахромы.

Но моя главная забота - это хорошее направление? И если да, то как я могу использовать функцию super()? Например, могу ли я найти super() полезным, если мне нужен тот же метод, но с другим возвратом? Или я должен в таком случае переопределить всю вещь? Или, может быть, вместо того, чтобы переписывать методы (не сохраняя большую часть кода), вместо того, чтобы переписывать методы, попробуйте сделать некоторые логические атрибуты в классе Node, которые изменят тип узла?

Я надеюсь, что это не слишком долго. Буду очень благодарен за любые мысли и идеи

+0

Я не уверен, что вы видели мой (обновленный) ответ, поэтому добавьте этот комментарий , я думаю, что он отвечает на все ваши вопросы и вопросы –

ответ

0

вы должны вернуть результат expand:

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

Если expand метод NodeStar класса точно так же, как и у Node класса нет необходимо переопределить метод в классе NodeStar (это часть наследования объектно-ориентированного программирования). Однако, если метод NodeStarexpand может сделать некоторые дополнительные функциональные возможности наряду с функциональностью оригинального expand метода, то вы можете повторно определить его и вызвать super.expand по мере необходимости, если это необходимо (это полиморфизм часть объектно-ориентированного программирования)

Что касается вас другие вопросы:

Object-Oriented programming предлагает некоторые основные понятия, как:

  1. Inheritance/Extension (DRY, то не-повторять сам)
  2. полиморфизм (подобный интерфейс для многогранного fuinctionality)
  3. Encapsulation (делает только интерфейс видимым, а основная реализация может изменяться по мере необходимости)

Таким образом, эти принципы, безусловно, могут быть полезными во многих ситуациях.Модель OO, которую вы пытаетесь реализовать с помощью вашего кода, представляет собой вариант того, что называется Composite pattern, ищите его для получения дополнительной информации и примеров

Фактически composite design pattern - это способ обработки как отдельных предметов, так и соединений предметов в форме путь. Это то, что вы пытаетесь сделать с классом Node (один элемент) и NodeStar (составной элемент, последовательность Node элементов)