Python 3, функция super() и наследование классов - это можно сделать даже так?

Это мой первый вопрос, поэтому я надеюсь, что не буду бросать слишком много вещей одновременно. Я реализую четыре разных алгоритма для решения задачи "Мир пылесосов". До сих пор я сделал четыре разных рабочих.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() при определении подкласса Node с именем NodeStar (для реализации 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?

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

1 ответ

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

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

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

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

Объектно-ориентированное программирование предлагает несколько основных понятий, таких как:

  1. Наследование / расширение (DRY, не повторяй себя)
  2. Полиморфизм (похожий интерфейс для многогранности)
  3. Инкапсуляция (сделать видимым только интерфейс, в то время как базовая реализация может изменяться по мере необходимости)

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

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

Другие вопросы по тегам