简体   繁体   English

python 3,super()函数和类继承-甚至可以通过这种方式完成吗?

[英]python 3, super() function and class inheritance - can it even be done this way?

this is my first question so I hope I won't throw too much stuff at once.. I'm implementing four different algorithms for a Vacuum Cleaner World problem . 这是我的第一个问题,所以我希望我不会一次扔太多东西。我正在为“ 吸尘器世界”问题实现四种不同的算法。 So far I made four different working .py files but I thought I would make it fancier since a lot of code is repeated and implement it all in one file with a nice class hierarchy. 到目前为止,我制作了四个不同的工作.py文件,但我想我会做得更好,因为重复了很多代码,并在一个具有良好类层次结构的文件中实现了所有这些代码。 So at first I had a Node class which looked a bit like this and was a bit different for each algorithm (breadth-first, A*, greedy and random): 因此,起初我有一个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

Now I'm trying to use super() function in defining a subclass of Node named NodeStar (for A* implementation): 现在,我尝试使用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()

Where 'self.heur', 'self.funH()' and 'self.prior' are attributes nad function which the Node class doesn't have. 其中“ self.heur”,“ self.funH()”和“ self.prior”是Node类所没有的attributes nad函数。 This code doesn't work. 此代码无效。 I got an error: 我收到一个错误:

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

(Notion on the side:) I don't know why I have to use arguments in super() function even though I installed python 3.4.3 on my computer (I work in Sublime Text 3 with Anaconda) (旁边的提示:)即使我在计算机上安装了python 3.4.3,我也不知道为什么我必须在super()函数中使用参数(我在Anaconda中使用Sublime Text 3)

I see that the problem is somehow related with the TreeSearch function where an expand() function was called on the first Node of the fringe. 我看到问题与TreeSearch函数有某种联系,在该函数的边缘的第一个Node上调用了expand()函数。

But my main concern is -- is it a good direction? 但是我主要关心的是-这是一个好的方向吗? And if so, how I am suppose to use the super() function? 如果是这样,我应该如何使用super()函数? For example can I find super() helpful if I need same method but with a different return? 例如,如果我需要相同的方法但返回的值不同,是否可以找到super()有用? Or should I, in such case, override entire thing? 还是在这种情况下我应该覆盖整个事情? Or perhaps should I instead of overwriting the methods (doesn't save much of a code) try to make some boolean attributes in the Node class that will change the type of Node? 或者,也许我不应该改写方法(不节省太多代码),而是尝试在Node类中创建一些布尔属性来改变Node的类型?

I hope that this isn't too long. 我希望这不会太长。 Will be very grateful for any thoughts and ideas 非常感谢您的任何想法和想法

you have to return the result of expand : 您必须返回expand的结果:

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

If the expand method of the NodeStar class is exactly the same as that of the Node class there is no need to re-define the method in the NodeStar class (this is the inheritance part of object-oriented programming). 如果expand的方法NodeStar类是完全一样的的Node类就没有必要重新定义的方法NodeStar类(这是面向对象编程的继承部分)。 However if the NodeStar expand method can do some additional functionality along with the functionality of the original expand method then you can re-define it and call the super.expand as needed if needed (this is the polymorphism part of object-oriented programming) 但是,如果NodeStar expand方法可以与原始expand方法一起执行某些附加功能,则可以根据需要重新定义它并调用super.expand (这是面向对象编程的多态性部分)

As regards you other questions: 关于您其他问题:

Object-Oriented programming offers some basic concepts like: 面向对象的编程提供了一些基本概念,例如:

  1. Inheritance / Extension (DRY, dont-repeat-yourself) 继承/扩展(DRY,请勿重复)
  2. Polymorphism (similar interface for many-faceted fuinctionality) 多态性(相似的界面,具有多方面的功能)
  3. Encapsulation (make only interface visible while underlying implementation can change as needed) 封装(仅使接口可见,而基础实现可以根据需要进行更改)

So these principles can certainly be helpful in many situations. 因此,这些原则在许多情况下肯定会有所帮助。 The OO pattern you try to implement with your code is a variation of what is refered as Composite pattern , look it up for further information and examples 您尝试用代码实现的OO模式是所谓的Composite模式的变体,请查找它以获取更多信息和示例。

Effectively the composite design pattern is a way to handle both single items and compounds of items in a uniform way. 实际上, composite design pattern是一种以统一的方式处理单个物料和物料复合物的方法。 This is what you (try to) do with the Node class (single item) and NodeStar class (compound item, sequence of Node items) 这是您(尝试)对Node类(单个项目)和NodeStar类(复合项目, Node项目序列)进行的操作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM