Python 继承方法的正确方法,带1个更正

Python 继承方法的正确方法,带1个更正,python,python-2.7,inheritance,Python,Python 2.7,Inheritance,我在做关于数据结构的家庭作业时,在python中进行了一点OOP实验,我在理解如何更正继承一些带有更正的方法时遇到了一些困难 因此,我: class BinarySearchTree(object): # snipped def _insert(self, key, val): prevNode = None currentNode = self.root while currentNode: prevNod

我在做关于数据结构的家庭作业时,在python中进行了一点OOP实验,我在理解如何更正继承一些带有更正的方法时遇到了一些困难

因此,我:

class BinarySearchTree(object):
    # snipped
    def _insert(self, key, val):
        prevNode = None
        currentNode = self.root
        while currentNode:
            prevNode = currentNode
            if key < currentNode.key:
                currentNode = currentNode.leftChild
            else:
                currentNode = currentNode.rightChild

        if key < prevNode.key:                      
            prevNode.leftChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.leftChild)            
        else:                                       
            prevNode.rightChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.rightChild)
    # snipped                
以及:

我的问题是:是否有一种聪明的方法可以继承这个方法并实现这个1 differenceprevNode.size+=1而不复制整个继承的函数代码

附言:对不起,我的英语不好

UPD:现在我无法在Scott和CAB的解决方案之间进行选择…

假设prevNode也是一个BTree或RBTree,您可以添加另一个方法,比如'updateSize',并包含行

prevNode.updateSize()
在BTree中,这将不起任何作用。但是,如果将RBTree设置为BTRee的子类,则可以重写此方法以将1添加到节点的大小。

假设prevNode也是BTRee或RBTree,则可以添加另一个方法,例如“updateSize”,并包括行

prevNode.updateSize()

在BTree中,这将不起任何作用。但是,如果将RBTree设置为BTRee的子类,则可以重写此方法,将1添加到节点的大小。

以下是使用访问者设计模式的建议

在这个模式中,您编写的是一个visitor方法,它明确地知道每个被访问的节点需要做什么

我们将更改基类以添加访问者功能

class BinarySearchTree(object):
# snipped
def _insert(self, key, val, visitor=None):   # Change here
    prevNode = None
    currentNode = self.root
    while currentNode:
        prevNode = currentNode
        if visitor: visitor(prevNode)       # Change here
        if key < currentNode.key:
            currentNode = currentNode.leftChild
        else:
            currentNode = currentNode.rightChild

    if key < prevNode.key:                      
        prevNode.leftChild = self.Node(key, val, parent=prevNode)
        self.updateNodeProperties(prevNode.leftChild)            
    else:                                       
        prevNode.rightChild = self.Node(key, val, parent=prevNode)
        self.updateNodeProperties(prevNode.rightChild)
# snipped   

这里有一个使用访问者设计模式的建议

在这个模式中,您编写的是一个visitor方法,它明确地知道每个被访问的节点需要做什么

我们将更改基类以添加访问者功能

class BinarySearchTree(object):
# snipped
def _insert(self, key, val, visitor=None):   # Change here
    prevNode = None
    currentNode = self.root
    while currentNode:
        prevNode = currentNode
        if visitor: visitor(prevNode)       # Change here
        if key < currentNode.key:
            currentNode = currentNode.leftChild
        else:
            currentNode = currentNode.rightChild

    if key < prevNode.key:                      
        prevNode.leftChild = self.Node(key, val, parent=prevNode)
        self.updateNodeProperties(prevNode.leftChild)            
    else:                                       
        prevNode.rightChild = self.Node(key, val, parent=prevNode)
        self.updateNodeProperties(prevNode.rightChild)
# snipped   

它并不十分优雅,但你可以这样做:

class BinarySearchTree(object):
    def _insert(self, key, val, update=False):
       prevNode = None
       currentNode = self.root
        while currentNode:
            prevNode = currentNode
            if update:
                prevNode.size += 1
            if key < currentNode.key:
                currentNode = currentNode.leftChild
            else:
                currentNode = currentNode.rightChild

        if key < prevNode.key:                      
            prevNode.leftChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.leftChild)            
        else:                                       
            prevNode.rightChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.rightChild)
    # snipped  

class RBTree(BinarySearchTree): 
    # snipped

    def _insert(self, key, val):
        super(RBTree, self)._insert(self, key, val, update=True)

我真的不喜欢这样,因为它在BinarySearchTree类中有代码来更新除了派生的RBTree类之外不存在的实例变量,但是由于这部分代码不应该为BinarySearchTree实例执行,所以不应该遇到NameError…

这不是很优雅,但你可以这样做:

class BinarySearchTree(object):
    def _insert(self, key, val, update=False):
       prevNode = None
       currentNode = self.root
        while currentNode:
            prevNode = currentNode
            if update:
                prevNode.size += 1
            if key < currentNode.key:
                currentNode = currentNode.leftChild
            else:
                currentNode = currentNode.rightChild

        if key < prevNode.key:                      
            prevNode.leftChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.leftChild)            
        else:                                       
            prevNode.rightChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.rightChild)
    # snipped  

class RBTree(BinarySearchTree): 
    # snipped

    def _insert(self, key, val):
        super(RBTree, self)._insert(self, key, val, update=True)

我真的不喜欢这样,因为它在BinarySearchTree类中有代码来更新除派生RBTree类之外不存在的实例变量,但由于这部分代码不应该为BinarySearchTree实例执行,所以不应该遇到NameError…

否。这就是您必须执行的操作。如果只修改一次节点,这是一回事,但由于它处于循环中,您只需重新实现该方法。您可以将prevNode.size+=self.something设置为默认值,并将其适当地设置为0。例如,树类中的代码应该管理树,而不是在节点本身中进行处理。一个很好的方法是访问者设计模式。你必须这样做。如果只修改一次节点,这是一回事,但由于它处于循环中,您只需重新实现该方法。您可以将prevNode.size+=self.something设置为默认值,并将其适当地设置为0。例如,树类中的代码应该管理树,而不是在节点本身中进行处理。一个很好的方法是访问者设计模式。Big thx,但是当你写答案时,我做了同样的事情,因为你对原始帖子的评论:Big thx,但是当你写答案时,我做了同样的事情,因为你对原始帖子的评论: