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
класс (это часть наследования объектно-ориентированного программирования). Однако если NodeStar
expand
Метод может сделать некоторые дополнительные функциональные возможности наряду с функциональностью оригинала expand
метод, то вы можете переопределить его и вызвать super.expand
при необходимости, если необходимо (это часть полиморфизма объектно-ориентированного программирования)
Что касается вас, другие вопросы:
Объектно-ориентированное программирование предлагает несколько основных понятий, таких как:
- Наследование / расширение (DRY, не повторяй себя)
- Полиморфизм (похожий интерфейс для многогранности)
- Инкапсуляция (сделать видимым только интерфейс, в то время как базовая реализация может изменяться по мере необходимости)
Таким образом, эти принципы, безусловно, могут быть полезны во многих ситуациях. Шаблон OO, который вы пытаетесь реализовать с помощью своего кода, представляет собой разновидность шаблона Composite, ищите его для получения дополнительной информации и примеров.
Эффективно composite design pattern
это способ работать как с отдельными предметами, так и с составами предметов единообразно. Это то, что вы (пытаетесь) делать с Node
класс (отдельный предмет) и NodeStar
класс (составной элемент, последовательность Node
Предметы)